4

无论出于何种原因,ThreadPool'sQueueWorkItem都不会返回IAsyncResult工作项的句柄或其他句柄,这将允许等待它完成。有一些RegisterWait...方法,但是您必须通过 aWaitHandle并且创建它们很昂贵(请参阅IAsyncResult文档,它建议您延迟创建 aWaitHandle直到请求)。Task Parallel Library 将解决这个缺陷,但在可用之前等待很长时间。那么,这个设计有什么问题吗:

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 时出现的问题的后续问题

4

2 回答 2

6

好吧,您在获取 WaitHandle 和设置它之间存在竞争条件。如果他们碰巧迟到了一点,你真的希望来电者永远等待吗?

您可能应该做一些适当的锁定并保留一个“我已经完成”标志,以便如果您在完成后创建 WaitHandle,您可以在返回之前设置它。

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

于 2009-01-02T00:25:12.867 回答
3

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

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

那会使 Concurrent 过时,不是吗?

于 2009-01-02T01:32:59.313 回答