C#线程,WaitHandle.WaitAll的 [英] C# Threads, WaitHandle.WaitAll

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

问题描述

这是可能没有不使用WaitHandle.WaitAll的(waitHandles)块WinForm的,但刚刚成立另一个线程时,从WaitHandle.WaitAll的获得complate信号,这将火?

Is that possible not not block winForm using WaitHandle.WaitAll(waitHandles) but just set another thread which will fire when get complate signal from WaitHandle.WaitAll?

推荐答案

我不会用 WaitHandle.WaitAll的。有一对夫妇使用这种方法的问题。

I would not use WaitHandle.WaitAll. There are a couple of problems with this approach.


  • 有一个64句柄限制。

  • 它不能在一个STA线程中使用。

  • 它促进依赖于建立多这显然消耗资源的WaitHandle 实例的模式。

  • There is a 64 handle limit.
  • It cannot be used on an STA thread.
  • It promotes patterns that depend on the creation of multiple WaitHandle instances which obviously consume resource.

相反,我通常使用 CountdownEvent 类时,我想等上多个事件。现在,你将拥有的问题是,它仍然需要你打电话等待在某些线程这是你正试图避免什么。标准的机制,以避免阻塞调用是使用 ThreadPool.RegisterWaitForSingleObject 方法。但不幸的是,需要一个的WaitHandle CountdownEvent 不会从类继承。

Instead, I typically use the CountdownEvent class when I want to wait on multiple events. Now, the problem you will have with that is that it still requires you to call Wait on some thread which is exactly what you are trying to avoid. The standard mechanism to avoid making a blocking call is to use the ThreadPool.RegisterWaitForSingleObject method. But, unfortunately that takes a WaitHandle and CountdownEvent does not inherit from that class.

解决方案是创建一个可以在 ThreadPool.RegisterWaitForSingleObject CountdownWaitHandle 类>方法。这种方法将允许您指定将一次执行的回调委托的的WaitHandle 发出信号。

The solution is to create your own CountdownWaitHandle class that can be used in the ThreadPool.RegisterWaitForSingleObject method. This approach will allow you to specify a callback delegate that will be executed once the WaitHandle is signaled.

下面是最基本实行的 CountdownWaitHandle 类。你必须添加所有必要的哈丁代码自己,但是这将让你开始

Here is the most basic implemenation for the CountdownWaitHandle class. You will have to add all of the necessary harding code yourself, but this will get you started.

public class CountdownWaitHandle : WaitHandle
{
    private int m_Count = 0;
    private ManualResetEvent m_Event = new ManualResetEvent(false);

    public CountdownWaitHandle(int initialCount)
    {
        m_Count = initialCount;
    }

    public void AddCount()
    {
        Interlocked.Increment(ref m_Count);
    }

    public void Signal()
    {
        if (Interlocked.Decrement(ref m_Count) == 0)
        {
            m_Event.Set();
        }
    }

    public override bool WaitOne()
    {
        return m_Event.WaitOne();
    }
}



这里的想法是,而不是使用许多不同的的WaitHandle 情况下,您使用一个 CountdownWaitHandle 实例。与所需的数初始化实例,然后调用信号来减少计数。一旦计数到达零,的WaitHandle 将进入信号状态。因此,而不是调用设置多个的WaitHandle 实例和 WaitHandle.WaitAll的你现在叫信号在这一个实例,并阻止通过调用的WaitOne 。再次,您可以通过使用推离阻塞调用线程池 TheadPool.RegisterWaitForSingleObject 将调用回调时,的WaitHandle 发出信号。

The idea here is that instead of using many different WaitHandle instances you use a single CountdownWaitHandle instance. Initialize the instance with the desired count and then call Signal to decrement the count. Once the count gets to zero the WaitHandle will go into the signaled state. So instead of calling Set on multiple WaitHandle instances and blocking with WaitHandle.WaitAll you now call Signal on this one instance and block by calling WaitOne. And again, you can push off the blocking call to the thread pool by using TheadPool.RegisterWaitForSingleObject which will invoke a callback when the WaitHandle is signaled.

这篇关于C#线程,WaitHandle.WaitAll的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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