检测ThreadPool WorkItem是否已完成/等待完成
无论出于何种原因, ThreadPool
的QueueWorkItem
不会返回IAsyncResult
或工作项的其他句柄,这将允许等到它完成。 有RegisterWait...
方法,但是你必须传递一个WaitHandle
并且创建它们很昂贵(参见IAsyncResult
文档,它建议你在请求之前延迟创建WaitHandle
)。 任务并行库将解决这个缺陷,但在可用之前需要等待很长时间。 那么,这个设计有什么问题:
public class Concurrent { private ManualResetEvent _resetEvent; private T _result; public Concurrent(Func f) { ThreadPool.QueueUserWorkItem(_ => { _result = f(); if (_resetEvent != null) _resetEvent.Set(); }); } public WaitHandle WaitHandle { get { if (_resetEvent == null) _resetEvent = new ManualResetEvent(_result != null); return _resetEvent; } ...
编辑:我问了一个关于使用异步委托而不是ThreadPool时出现的问题的后续问题 。
好吧,你在获取WaitHandle和设置它之间遇到了竞争条件。 如果他们碰巧有点迟到,你真的希望呼叫者永远等待吗?
你应该做一些适当的锁定并保持一个“我已经完成”的标志,这样如果你在完成后创建了WaitHandle,你可以在返回它之前设置它。
我还亲自编写一个静态工厂方法,而不仅仅是使用公共构造函数 – 或者使其成为“创建然后显式启动”模式。 在构造函数中排队工作项对我来说很奇怪。