检测线程组何时完成的最佳实践
检测整组线程何时完成处理的最佳实践是什么? 我有一个进程将查询[长时间运行的] Web 服务以获取任意数量的对象,然后需要在所有对象都成功完成时采取事务操作。 我目前正在使用 .Net 线程池中的委托异步运行它们。 同步运行它们,违背了在多个线程上运行它们的目的......我还能如何检测所有线程何时完成? 我想使用一个计数器(又名 COM 引用计数)来增加它以到达启动的线程并在回调函数中减少它,并保留一个动态列表,其中包含对其中每个线程的引用,以显式跟踪每个线程当它们完成时,但这两个解决方案似乎都有点混乱...
感谢所有人...基于您的建议,并且需要将对象实例传递给异步线程(由下面的 ref 变量 uPL 表示),我是使用以下代码... 注意:IEEDAL.GetUsagePayloadReadings(uPL1) 是远程 Web 服务调用
foreach (MeterChannel chgChan in chgChs)
foreach (UsagePayload uPL in chgChan.IntervalPayloads)
{
ManualResetEvent txEvnt = new ManualResetEvent(false);
UsagePayload uPL1 = uPL;
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
if (!uPL1.HasData)
IEEDAL.GetUsagePayloadReadings(uPL1);
UsageCache.PersistPayload(uPL1);
SavePayLoadToProcessFolder(uPL1);
txEvnt.Set();
} );
waitHndls.Add(txEvnt);
}
WaitHandle.WaitAll(waitHndls.ToArray());
What's the best practice for detecting when a whole group of threads are done processing? I have a process that will query a [long running] web service for an arbitrary number of objects, and then needs to take a transactional action when all of them have completed successfully. I am currently running them asynchronously, using delegates from the .Net thread pool. Running them synchronously, defeats the purpose of running them on multiple threads... How else can I detect when ALL are finished? I though of using a coounter, (aka COM referece count) incrementing it for reach thread that starts and decrementing it in a callback function, and of keeping a dynamic list with a reference to each thread in it, to explicitly keep track of each one as they complete, but both of these solutions seem kinda kludgy...
Thanks to all... Based on yr suggestions, and on need to pass an object instance to the aynchronous thread, (represented by ref variable uPL below), I am using the following code... NOTE: IEEDAL.GetUsagePayloadReadings(uPL1) is the remote web service call
foreach (MeterChannel chgChan in chgChs)
foreach (UsagePayload uPL in chgChan.IntervalPayloads)
{
ManualResetEvent txEvnt = new ManualResetEvent(false);
UsagePayload uPL1 = uPL;
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
if (!uPL1.HasData)
IEEDAL.GetUsagePayloadReadings(uPL1);
UsageCache.PersistPayload(uPL1);
SavePayLoadToProcessFolder(uPL1);
txEvnt.Set();
} );
waitHndls.Add(txEvnt);
}
WaitHandle.WaitAll(waitHndls.ToArray());
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用WaitHandle.WaitAll。
You can use WaitHandle.WaitAll.
我见过的最好的方法是使用倒计时锁存器。 2007 年 5 月有一个非常好的描述,包括 C# 源代码MSDN 杂志的一期。
The best way I've seen to do this is to use a countdown latch. There's a very good description, including C# source, in the May 2007 issue of MSDN Magazine.
有几个选择。
信号量让您可以在所有线程中使用计数器。 如果您确切知道有多少个,则可以使用它来检查它们何时完成。
另一种可能的替代方案是为每个线程提供一个 ResetEvent。 只需将事件设置在线程的“末尾”,然后在主线程中检查它们即可。 不过,这可能会更困难。
There are a couple of options.
A Semaphore lets you have a counter used across all of your threads. If you know exactly how many there are, you can use this to check for when they're completed.
Another potential alternative is to have a ResetEvent for each thread. Just set the event at the "end" of the thread, and check them in your main thread. This may be more difficult, though.
我不知道这是否是一种“最佳实践”,但是 System.Threading.ManualResetEvent 和 System.Threading.WaitHandle 类是我发现当线程需要相互发送信号时不可或缺的两个类。 下面是如何将它们与 ThreadPool 线程一起使用的基本示例。
I don't know if it's a "best practice" or not, but the System.Threading.ManualResetEvent and System.Threading.WaitHandle classes are two classes that I find indispensable when threads need to signal one another. Here is a rudimentary example of how to use them with ThreadPool threads.