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占用
}
}
-
双阶段处理:
-
完成检查:遍历
execed
字典,调用EndInvoke
并清理已完成任务。 -
任务启动:从
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);
改进建议
-
异常传递
当前静默忽略所有异常,可增加ErrorOccurred
事件通知调用方。 -
资源释放
实现IDisposable
接口,终止线程并清理资源。 -
动态管道扩展
当前Set
方法不自动扩展队列,需提前InitQueue
,可优化为动态扩容。 -
优先级控制
允许为不同管道任务设置优先级。
总结
DelegateSpooler
是一个高效的异步任务调度器,其核心优势在于:
-
轻量级管道管理:通过管道ID隔离不同任务流。
-
可靠的异步机制:结合
BeginInvoke
和轮询检查确保任务完成。 -
低侵入性设计:对调用方隐藏线程管理细节。
适用于需要 多任务异步调度 的场景(如事件处理、批量作业执行等)。