Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测到线程池工作项已完成/正在等待完成_C#_Multithreading_Asynchronous_Concurrency_Threadpool - Fatal编程技术网

C# 检测到线程池工作项已完成/正在等待完成

C# 检测到线程池工作项已完成/正在等待完成,c#,multithreading,asynchronous,concurrency,threadpool,C#,Multithreading,Asynchronous,Concurrency,Threadpool,无论出于何种原因,ThreadPool的QueueWorkItem都不会返回工作项的IAsyncResult或其他句柄,这将允许等待工作项完成。有RegisterWait…方法,但您必须传递WaitHandle并且创建它们的成本很高(请参阅IAsyncResult文档,该文档建议您延迟创建WaitHandle,直到请求为止)。任务并行库将修复这一缺陷,但这需要很长时间才能实现。那么,这种设计有什么问题吗 public class Concurrent<T> { private

无论出于何种原因,
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;
        }

    ...
公共类并发{
私人手册重置事件_重置事件;
私人T_结果;
公共并发(Func f){
ThreadPool.QueueUserWorkItem(=>{
_结果=f();
如果(_resetEvent!=null)
_resetEvent.Set();
});
}
公共WaitHandle WaitHandle{
得到{
如果(_resetEvent==null)
_resetEvent=新的ManualResetEvent(_结果!=null);
返回重置事件;
}
...
编辑:
我问了一个问题。

嗯,在获取WaitHandle和设置WaitHandle之间有一个竞争条件。你真的想让打电话的人永远等待,如果他们碰巧迟到了一点点吗

您可能应该执行一些适当的锁定,并保留一个“I have finished”标志,这样,如果您在WaitHandle完成后创建它,那么您可以在返回它之前设置它


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

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


这将使并发过时,不?

请注意,我将
\u result!=null
作为参数传递给ManualResetEvent构造函数。(这对结构不起作用,但想法是一样的。)
\u result!=null
作为此处的结束标志(当然不是在实际实现中).是的,这里需要明智的锁定。(续…)一个静态的工厂方法不用说,我很少写一个通用的公共构造函数而不需要一个相应的静态方法。不过,我不会首先将构造函数公开。你也应该考虑返回空的方法……如我所说的,<代码>(如果方法抛出异常,这也会很糟糕。)1)并发提供了一个更容易使用的API(我认为);2)并发只是未来的一个子类型,还有其他子类型的工作方式不同(惰性值、承诺);3)(最重要)因为我没有注意到并发可以实现为异步委托上的一个门面。啊,我从一开始就认为这与未来有关:-)。