是否可能不使用 WaitHandle.WaitAll(waitHandles) 阻止 winForm,而只是设置另一个线程,当从 WaitHandle.WaitAll 获取 complate 信号时将触发该线程?
我不会使用WaitHandle.WaitAll
。这种方法存在一些问题。
- 有 64 个句柄限制。
- 它不能在 STA 线程上使用。
- 它促进了依赖于多个创建的模式
WaitHandle
明显消耗资源的实例。
相反,我通常使用CountdownEvent
当我想等待多个事件时。现在,您将遇到的问题是它仍然需要您致电Wait
在某些线程上,这正是您想要避免的。避免进行阻塞调用的标准机制是使用ThreadPool.RegisterWaitForSingleObject
方法。但是,不幸的是,这需要WaitHandle
and CountdownEvent
不继承该类。
解决方案是创建自己的CountdownWaitHandle
可以使用的类ThreadPool.RegisterWaitForSingleObject
方法。这种方法将允许您指定一个回调委托,一旦WaitHandle
已发出信号。
这是最基本的实现CountdownWaitHandle
班级。您必须自己添加所有必要的硬编码,但这将帮助您入门。
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
实例。使用所需的计数初始化实例,然后调用Signal
减少计数。一旦计数归零WaitHandle
将进入有信号状态。所以而不是打电话Set
在多个WaitHandle
实例并阻止WaitHandle.WaitAll
你现在打电话Signal
在这个实例上并通过调用阻止WaitOne
。同样,您可以使用以下方法推迟对线程池的阻塞调用TheadPool.RegisterWaitForSingleObject
当WaitHandle
已发出信号。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)