当应一个ManualResetEvent的处置? [英] When should a ManualResetEvent be disposed?

查看:136
本文介绍了当应一个ManualResetEvent的处置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用,使用的ManualResetEvent同步线程的应用程序。 FxCop的叫我处理这些对象。我发现下面的讨论,这跟我是一样的:

I'm using an application that synchronizes threads using ManualResetEvent. FxCop told me to dispose those objects. I found the following discussion which told me the same:

我需要的Dispose()或关闭()一个的EventWaitHandle?

但我不知道什么时候才能处理一个ManualResetEvent的实例。

But I don't know when to dispose an instance of a ManualResetEvent.

以下简化code演示了此问题:

The following simplified code demonstrates the problem:

private void btn_Click(object sender, EventArgs e)
{
    var mre = new ManualResetEvent(false);
    new Thread(() => this.SetEvent(mre)).Start();
    for (int i = 0; i < 10; ++i)
    {
        new Thread(() => this.WaitFor(mre)).Start();
    }
}

private void SetEvent(ManualResetEvent manualResetEvent)
{
    Thread.Sleep(10000);
    manualResetEvent.Set();
}

private void WaitFor(ManualResetEvent manualResetEvent)
{
    manualResetEvent.WaitOne();
}

的问题是,ManualResetEvent的多个实例存在和多个线程正在等待对每个实例

The problem is that multiple instances of the ManualResetEvent exist and multiple threads are waiting for each instance.

如果我记得你在列表中的情况下,我不知道什么时候处理掉它。 WaitOne的()之后废掉了它 - 通话将处理它多次,也许它会被处理,而其他线程仍在等待

If I memorize the instances in a list I don't know when to dispose it. Disposing it after WaitOne()-call will dispose it multiple times and maybe it will be disposed while other threads are still waiting.

创建该事件没有任何提及它的线程。二传手线程应该不会出售,因为有等待这个MRE其他线程。每一个等待的线程是不是能够处理它如前所述。

The thread that created the event doesn't have any reference to it. The setter-thread should not dispose it because there are other threads waiting for this MRE. Each waiting thread isn't able to dispose it as mentioned before.

所以现在的问题是:什么时候应该这样的ManualResetEvent处置

So the question is: When should this ManualResetEvent be disposed?

推荐答案

的ManualResetEvent 应处置时,你不再需要它。你真正的问题是,我怎么知道,我不再需要它吗?

The ManualResetEvent should be disposed when you no longer need it. Your real question is, "how do I know that I no longer need it?"

通常的东西被通知当线程完成,而你打电话加入的线程上。或线程设置一些事件,以指示它已完成。如果你有多个线程,它们都可以预示着 CountdownEvent 。还有一些其他的方法来管理线程的通知。

Typically something is notified when threads are done, and you call Join on the thread. Or the thread sets some event to indicate that it has finished. If you have multiple threads, they can all signal a CountdownEvent. There are several other ways to manage thread notification.

的一点是,如果你在资源配置是由你来确保他们正确地处理。在您的code以上,你没有任何办法来跟踪这些线程正在执行或线程关联与的ManualResetEvent 。如果你想确保MRE被妥善处理,那么你必须跟踪它,不仅其线程都在使用它,这线程完成自己的工作跟踪麦格理又和通知时,所有的线程完成,这样就可以处理掉的东西。

The point is that if you're allocating resources it's up to you to make sure they're disposed correctly. In your code above, you don't have any way to keep track of which threads are executing or which threads are associated with which ManualResetEvent. If you want to make sure that the MRE is disposed of properly, then you have to track it, not only keep track of the MRE but also which threads are using it, which threads have completed their work, and be notified when all of the threads are done so that you can dispose of things.

在你的特殊情况下,如果你真的要使用MRE这样一来,我可能会创建一个包含对线程和MRE,和数据结构的 CountdownEvent 的主题时,他们完成信号。是这样的:

In your particular situation, if you really have to use an MRE this way, I would probably create a data structure that contains references to the threads and the MRE, and a CountdownEvent that the threads signal when they're done. Something like:

class WorkUnit
{
    public List<Thread> Threads;
    public ManualResetEvent MRE;
    public CountdownEvent CE;
}

现在,当一个线程完成它这样做:

Now, when a thread finishes it does this:

workUnit.CE.Signal();

你的程序(可能是主线程)的其他部分周期性地检查工作单位的名单。对于该列表中的每个项目它这样做:

Some other part of your program (probably the main thread) checks the list of work units periodically. For each item in that list it does this:

if (workUnit.CE.WaitOne(0))
{
    foreach (Thread t in workUnit.Threads)
    {
        t.Join();
    }
    // dispose the MRE and the CE
    // and remove the work unit from the list
}

是的,这是一个很大的工作。这也可能是最好的,如果你能构建程序,这样你就不必做这种事情。

Yes, it's a lot of work. It's probably best if you can structure your program so that you don't have to do this kind of thing.

这篇关于当应一个ManualResetEvent的处置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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