gpt4 book ai didi

c# - 多线程-等待所有线程发出信号

转载 作者:行者123 更新时间:2023-12-03 12:50:56 25 4
gpt4 key购买 nike

在某些情况下,我需要一个主线程来等待,直到一组可能超过64个线程中的每个线程都完成工作为止,为此,我编写了以下帮助程序实用程序(以避免对WaitHandle.WaitAll()设置64个waithandle限制)

    public static void WaitAll(WaitHandle[] handles)
{
if (handles == null)
throw new ArgumentNullException("handles",
"WaitHandle[] handles was null");
foreach (WaitHandle wh in handles) wh.WaitOne();
}

但是,使用此实用程序方法时,仅在信号通知数组中的每个前一个等待句柄之后,才检查每个等待句柄...因此它实际上是同步的,并且如果等待句柄是autoResetEvent等待句柄(则在等待线程已被释放)

为了解决这个问题,我正在考虑将此代码更改为以下代码,但希望其他人检查一下它是否看起来可以正常工作,或者是否有人看到它的任何问题,或者可以提出更好的方法...

提前致谢:
    public static void WaitAllParallel(WaitHandle[] handles)
{
if (handles == null)
throw new ArgumentNullException("handles",
"WaitHandle[] handles was null");
int actThreadCount = handles.Length;
object locker = new object();
foreach (WaitHandle wh in handles)
{
WaitHandle qwH = wh;
ThreadPool.QueueUserWorkItem(
delegate
{
try { qwH.WaitOne(); }
finally { lock(locker) --actThreadCount; }
});
}
while (actThreadCount > 0) Thread.Sleep(80);
}

最佳答案

如果知道您有多少个线程,则可以使用互锁递减。这是我通常的做法:

 {
eventDone = new AutoResetEvent();
totalCount = 128;
for(0...128) {ThreadPool.QueueUserWorkItem(ThreadWorker, ...);}
}

void ThreadWorker(object state)
try
{
... work and more work
}
finally
{
int runningCount = Interlocked.Decrement(ref totalCount);
if (0 == runningCount)
{
// This is the last thread, notify the waiters
eventDone.Set();
}
}

实际上,大多数时候我什至不发信号,而是调用回调从服务员将要继续的地方继续进行处理。更少的阻塞线程,更多的可伸缩性。

我知道这是不同的,并且可能不适用于您的情况(例如,如果某些thoe句柄不是线程,而是I/O或事件,则肯定无法使用),但是值得对此进行思考。

关于c# - 多线程-等待所有线程发出信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1982572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com