【发布时间】:2013-01-02 05:59:12
【问题描述】:
这段代码大部分时间都有效,所以我在考虑一些竞争条件。 Result 类是不可变的,但我认为问题不在于该类。
public Result GetResult()
{
using (var waitHandle = new ManualResetEvent(false))
{
Result result = null;
var completedHandler = new WorkCompletedEventHandler((o, e) =>
{
result = e.Result;
// somehow waitHandle is closed, thus exception occurs here
waitHandle.Set();
});
try
{
this.worker.Completed += completedHandler;
// starts working on separate thread
// when done, this.worker invokes its Completed event
this.worker.RunWork();
waitHandle.WaitOne();
return new WorkResult(result);
}
finally
{
this.worker.Completed -= completedHandler;
}
}
}
编辑:抱歉,我在调用 GetResult() 方法之前错过了对 this.worker.RunWork() 的调用。这显然导致(有时)两次执行相同的工作,尽管我不确定为什么 waitHandle 在 waitHandle.Set() 之前关闭,尽管 Completed 事件触发了两次。这根本没有影响 IO 工作(结果是正确的;在我更改代码以手动关闭 waitHandle 之后)。
因此,Iridium's answer 应该是最接近的答案(如果不是正确的答案),即使问题不完整。
【问题讨论】:
-
由于您的 using 子句,waithandle 已经被调用。如果你在完成的事件处理程序中处理等待句柄,你应该没问题。
-
不,WaitHandle,在大多数情况下,在工作完成后被释放(参见 waitHandle.WaitOne() after this. worker.RunWork())
-
那么在这种情况下,您必须等到其他人给出答案。
-
ReSharper 允许访问已处理的关闭错误
-
参见 waitHandle.WaitOne() - waitHandle 不应该被释放(它应该在 waitHandle 发出信号后被释放)。
标签: c# multithreading waithandle