异步委托任务队列管理器DelegateSpooler类实现

internal class DelegateSpooler
{
    private Thread worker;

    private List<ThreadStart> delegates = new List<ThreadStart>();

    private Dictionary<int, KeyValuePair<ThreadStart, IAsyncResult>> execed = new Dictionary<int, KeyValuePair<ThreadStart, IAsyncResult>>();

    internal DelegateSpooler(string name)
    {
        worker = new Thread(InternalUtilities.WrapDelegateForCulture(bgWorker));
        worker.Name = typeof(DelegateSpooler).Name + "<" + name + ">";
        worker.IsBackground = true;
        worker.Start();
    }

    public void Set(int pipe, ThreadStart del)
    {
        lock (delegates)
        {
            if (0 <= pipe && pipe < delegates.Count)
            {
                delegates[pipe] = del;
            }
        }
    }

    internal void ClearQueue()
    {
        lock (delegates)
        {
            delegates.Clear();
        }
    }

    internal void InitQueue(int pipes)
    {
        lock (delegates)
        {
            delegates.Clear();
            delegates.AddRange(new ThreadStart[pipes]);
        }
    }

    internal bool IsPipeExecuting(int pipe)
    {
        return execed.ContainsKey(pipe);
    }

    private void bgWorker()
    {
        while (true)
        {
            try
            {
                foreach (int item in new List<int>(execed.Keys))
                {
                    if (execed[item].Value.IsCompleted)
                    {
                        try
                        {
                            execed[item].Key.EndInvoke(execed[item].Value);
                        }
                        catch
                        {
                        }

                        execed.Remove(item);
                    }
                }

                lock (delegates)
                {
                    for (int i = 0; i < delegates.Count; i++)
                    {
                        if (delegates[i] != null && !execed.ContainsKey(i))
                        {
                            ThreadStart threadStart = InternalUtilities.WrapDelegateForCulture(delegates[i]);
                            execed[i] = new KeyValuePair<ThreadStart, IAsyncResult>(threadStart, threadStart.BeginInvoke(null, null));
                            delegates[i] = null;
                        }
                    }
                }

                Thread.Sleep(10);
            }
            catch (ThreadInterruptedException)
            {
                break;
            }
            catch
            {
            }
        }
    }
}

1. 核心功能

这是一个 异步委托任务队列管理器,核心功能包括:

  • 多管道委托任务调度:通过 pipe(管道ID)管理不同任务的执行状态。

  • 异步调用与回调处理:使用 BeginInvoke/EndInvoke 实现异步执行。

  • 线程安全的任务管理:支持动态添加、清理和状态检查。


2. 关键成员分析

(1)任务存储结构
  • delegates 列表
    存储待执行的委托任务(ThreadStart),索引对应 pipe ID。

  • execed 字典
    记录正在执行的任务:
    Key = 管道ID,
    Value = 委托及其 IAsyncResult 句柄。

(2)后台工作线程
  • worker 线程
    持续运行 bgWorker 方法,轮询处理任务队列。

  • 线程配置

    • 命名为 DelegateSpooler<name>(构造函数传入)。

    • 设置为后台线程(IsBackground = true)。


3. 核心方法解析

(1)任务管理
  • Set(int pipe, ThreadStart del)

public void Set(int pipe, ThreadStart del) {
    lock (delegates) {
        if (0 <= pipe && pipe < delegates.Count) {
            delegates[pipe] = del; // 更新指定管道的任务
        }
    }
}
    • 线程安全地设置指定管道的任务(若管道ID有效)。

  • InitQueue(int pipes)

internal void InitQueue(int pipes) {
    lock (delegates) {
        delegates.Clear();
        delegates.AddRange(new ThreadStart[pipes]); // 初始化空任务队列
    }
}
    • 重置队列并分配指定数量的管道。

(2)状态检查
  • IsPipeExecuting(int pipe)

internal bool IsPipeExecuting(int pipe) {
    return execed.ContainsKey(pipe); // 检查指定管道是否有任务正在执行
}
(3)后台轮询逻辑(bgWorker)
private void bgWorker() {
    while (true) {
        // 1. 检查已完成的任务
        foreach (var pipe in new List<int>(execed.Keys)) {
            if (execed[pipe].Value.IsCompleted) {
                try {
                    execed[pipe].Key.EndInvoke(execed[pipe].Value); // 触发回调
                } catch { /* 忽略异常 */ }
                execed.Remove(pipe); // 清理已完成任务
            }
        }

        // 2. 启动新任务
        lock (delegates) {
            for (int i = 0; i < delegates.Count; i++) {
                if (delegates[i] != null && !execed.ContainsKey(i)) {
                    var task = delegates[i];
                    execed[i] = new KeyValuePair<ThreadStart, IAsyncResult>(
                        task,
                        task.BeginInvoke(null, null) // 异步执行
                    );
                    delegates[i] = null; // 标记为已调度
                }
            }
        }

        Thread.Sleep(10); // 降低CPU占用
    }
}
  • 双阶段处理

    1. 完成检查:遍历 execed 字典,调用 EndInvoke 并清理已完成任务。

    2. 任务启动:从 delegates 中取出待执行任务,异步调用后移至 execed

  • 异常处理:静默捕获所有异常,确保线程不终止。


4. 线程安全设计

  • lock(delegates)
    保护 delegates 列表的所有操作(Set/InitQueue/bgWorker)。

  • execed 的隐式安全
    由于仅在 bgWorker 线程内修改,无需额外锁。


5. 典型使用场景

var spooler = new DelegateSpooler("TaskQueue");
spooler.InitQueue(5); // 初始化5个管道

// 添加任务到管道1
spooler.Set(1, () => Console.WriteLine("Task 1"));

// 检查管道1是否在执行
bool isRunning = spooler.IsPipeExecuting(1);

改进建议

  1. 异常传递
    当前静默忽略所有异常,可增加 ErrorOccurred 事件通知调用方。

  2. 资源释放
    实现 IDisposable 接口,终止线程并清理资源。

  3. 动态管道扩展
    当前 Set 方法不自动扩展队列,需提前 InitQueue,可优化为动态扩容。

  4. 优先级控制
    允许为不同管道任务设置优先级。


总结

DelegateSpooler 是一个高效的异步任务调度器,其核心优势在于:

  • 轻量级管道管理:通过管道ID隔离不同任务流。

  • 可靠的异步机制:结合 BeginInvoke 和轮询检查确保任务完成。

  • 低侵入性设计:对调用方隐藏线程管理细节。

适用于需要 多任务异步调度 的场景(如事件处理、批量作业执行等)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值