处理基本线程同步的双向andle
-
21-12-2019 - |
题
根据文档,应该明确/隐式地处理.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();
. 不隶属于 StackOverflow