根据文档,应明确/隐含地处理.NET中的WaitHandle。但是,我无法在以下基本同步任务中实现此目的:
这里我尝试使用AutoResetEvent对象:
using(var waitHandle = new AutoResetEvent(false)){
var worker = new Thread(() =>
{
try
{
TimeConsumingTask();
waitHandle.Set(); //throws System.ObjectDisposedException: Safe handle has been closed
}
catch (Exception e)
{...}
}) {IsBackground = true};
worker.Start(); //start worker
const int waitTimeInMs = 5000;
var signaled = waitHandle.WaitOne(waitTimeInMs);//block main thread here.
if (!signaled)
{ //if timed out
worker.Interrupt();
}
}
有一个明显的竞争条件,主线程等待超时并处理导致ObjectDisposedException异常的等待句柄对象。有没有其他方法我设置它以便正确处理句柄,而不会导致异常?
答案 0 :(得分:4)
当然,没有合适的方法可以做到这一点。请事先注意你自己画了一个角落,基本上留下一个疯狂的线程,没有什么特别好的。
但是你专注于更小的问题。 Thread类本身已经是资源占用,消耗了一兆字节的VM和五个同步对象。但它没有Dispose()方法。这是勇敢的设计,没有合适的方法来调用该方法。
处置可选,当你不打电话时,没有任何戏剧性的事情发生。该类已经退缩,它有一个终结器,可确保释放本机操作系统资源。哪个将运行,最终,不会像你一样快。
将此与具有较少勇敢设计的类相比较,Task类具有Dispose()方法。像Thread一样,几乎同样难以调用。 guidance from the .NET gurus只是不打扰。
同样在这里。
答案 1 :(得分:0)
waithandle正在处理,因为你的使用范围调用一个新的线程立即返回,导致waithandle被处置。
您应该做的是在完成工作后明确调用dispose而不是using语句:
waitHandle.WaitOne(waitTimeInMs);
if (!signaled)
{ //if timed out
worker.Interrupt();
}
waitHandle.Dispose();