为基本线程同步处理 WaitHandle [英] Dispose WaitHandle for basic thread synchronization

查看:34
本文介绍了为基本线程同步处理 WaitHandle的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据文档,.NET 中的 WaitHandle 应显式/隐式处理.但是,对于以下基本同步任务,我无法实现此目标:

According to documentation, WaitHandle in .NET should be explicitly/implicitly disposed. However, I'm having trouble achieving this for the following basic synchronization task:

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

这里我尝试使用 AutoResetEvent 对象:

Here my attempt at using an AutoResetEvent object:

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 异常的等待句柄对象.有没有其他方法可以设置它以便正确处理句柄并且不会导致异常?

There is an obvious race condition where the main thread wait times out and disposes the wait handle object which causes ObjectDisposedException exception. Is there any other way that I set this up so that the handle is properly disposed and without causing the exception?

推荐答案

当然,没有合适的方法来做到这一点.请事先注意,你通过基本上让一个线程疯狂地把自己画到那个角落,没有什么特别好的.

Sure, there's no decent way to do this. Do note up front that you painted yourself into that corner by essentially leaving a thread running wild, nothing particularly nice about that.

但是您专注于小得多的问题.Thread 类本身已经是一个资源猪,消耗了 1 兆字节的 VM 和五个同步对象.但它没有 Dispose() 方法.这是一个勇敢的设计,只是没有像样的方法来调用这个方法.

But you are focusing on the much smaller problem. The Thread class itself is already a resource hog, consuming a megabyte of VM and five synchronization objects. But it has no Dispose() method. This was courageous design, there's just no decent way to call the method.

处置是可选,当您不调用它时,不会发生任何戏剧性的事情.这个类已经得到了你的支持,它有一个终结器来确保本机操作系统资源将被释放.哪个运行,最终,只是没有你想要的那么快.

Disposing is optional, nothing that dramatic happens when you don't call it. The class has got your back, it has a finalizer that ensures that the native operating system resource will be released. Which will run, eventually, just not as quickly as you'd like.

将此与设计不那么大胆的类进行比较,Task 类具有 Dispose() 方法.与 Thread 一样,它几乎同样难以调用.来自 .NET 专家的指导只是不打扰.

Compare this to a class with a less courageous design, the Task class has a Dispose() method. Which, like Thread, is almost as hard to call. The guidance from the .NET gurus is to just not bother.

这里也一样.

这篇关于为基本线程同步处理 WaitHandle的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆