根据文档,应该明确/隐式地处理.NET中的WATHANDLE。但是,对于以下基本同步任务,我无法实现此操作:

  • 在线程上执行耗时的任务。
  • 主线程等待任务完成预定义的时间段。如果a,主线程必须继续。任务完成或b。超时发生。

在这里我尝试使用autoreetevent对象:

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异常。是否有任何其他方法可以将其设置为,以便句柄正确地处理,而不会导致异常?

有帮助吗?

解决方案

当然,没有体面的方式来做这件事。注意到你将自己画成那个角落,基本上留下一个狂野的螺纹,没有什么特别好的。

但你专注于更小的问题。线程类本身已经是一个资源猪,消耗兆字节的VM和五个同步对象。但它没有Dispose()方法。这是勇敢的设计,只有没有体面的方式来调用方法。

处理是可选的,没有什么可以在不打电话的时候发生戏剧性。该类备受您的背部,它有一个终结器,可确保本机操作系统资源将被释放。哪个运行,最终,不像你想要的那样快速。

将此与具有更少勇敢的设计的类进行比较,任务类具有Dispose()方法。像线程一样,几乎难以打电话。 来自.Net Gurus 的指导是只是不打扰。

同样。

其他提示

waithandle正在处理,因为您的使用范围会立即调用一个新线程,导致waithandle处理。

您应该做的是明确地呼叫完成工作后,而不是使用语句:

waitHandle.WaitOne(waitTimeInMs);
if (!signaled)
{ //if timed out
   worker.Interrupt();
}
waitHandle.Dispose();
.

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