无论出于何种原因, ThreadPool QueueWorkItem 不会返回 IAsyncResult 或工作项的其他句柄,这将允许等到它完成。有 RegisterWait ... 方法,但你必须传递 WaitHandle 并且创建它们很昂贵(参见 IAsyncResult 文档,它建议你延迟创建 WaitHandle 直到请求为止。任务并行库将解决这个问题,但在可用之前需要等待很长时间。那么,这个设计有什么问题:

public class Concurrent<T> {
    private ManualResetEvent _resetEvent;
    private T _result;

    public Concurrent(Func<T> 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,你可以在返回之前设置它。

我还会亲自编写一个静态工厂方法,而不仅仅是使用公共构造函数 - 或者将其设为“create and 然后显式启动”。图案。在构造函数中排队工作项对我来说很奇怪。

其他提示

为什么不使用异步委托,如下所示:

http://msdn.microsoft.com/en-us/library /h80ttd5f.aspx

那会使Concurrent过时,不是吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top