欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

如何实现线程池的 QueueUserWorkItem 方法的延续?

发布时间:2023/12/4 48 豆豆
生活随笔 收集整理的这篇文章主要介绍了 如何实现线程池的 QueueUserWorkItem 方法的延续? 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

咨询区

  • PedroC88

如果我将 Job 通过 QueueUserWorkItem 方法丢到线程池的话,请问我如何让程序在该 Job 完成后继续执行,我知道可以添加一些逻辑代码来完成此项功能,但我想知道有没有类似 Thread.Join() 或者怎么提取到被赋于 job 的线程 ?

回答区

  • Alex Aza

你可以使用类似 ManualResetEvent 内核事件去同步,参考下面代码:

private static ManualResetEvent resetEvent = new ManualResetEvent(false);public static void Main() {ThreadPool.QueueUserWorkItem(arg => DoWork());resetEvent.WaitOne(); }public static void DoWork() {Thread.Sleep(5000);resetEvent.Set(); }

如果不想把 event 嵌入到 方法中,可以在 QueueUserWorkItem 委托方法中执行,比如下面这样。

var resetEvent = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(arg => {DoWork();resetEvent.Set();}); resetEvent.WaitOne();

对于批量操作,可以定义一个 List<ManualResetEvent> 。

var events = new List<ManualResetEvent>();foreach(var job in jobs) {   var resetEvent = new ManualResetEvent(false);ThreadPool.QueueUserWorkItem(arg =>{DoWork(job);resetEvent.Set();});events.Add(resetEvent); } WaitHandle.WaitAll(events.ToArray());
  • Brian Gideon

可以用 CountdownEvent 或者 Barrier 来做同步。

Barrier barrier = new Barrier(3);  for(int i = 0; i < 2; i++) {ThreadPool.QueueUserWorkItem((state) =>{foo();barrier.SignalAndWait();}, null); } barrier.SignalAndWait();/* 或者*/using (var finished = new CountdownEvent(1)) {foreach (var workitem in workitems){var capture = workitem; // Used to capture the loop variable in the lambda expression.finished.AddCount(); // Indicate that there is another work item.ThreadPool.QueueUserWorkItem((state) =>{try{ProcessWorkItem(capture);}finally{finished.Signal(); // Signal that the work item is complete.}}, null);}finished.Signal(); // Signal that queueing is complete.finished.Wait(); // Wait for all work items to complete. }

点评区

如果一定要在 QueueUserWorkItem 中拦截,最好的方式还是用各种锁比较好,如果在实际开发中,建议还是用 Task,它具有强大的编排能力。

创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖

总结

以上是生活随笔为你收集整理的如何实现线程池的 QueueUserWorkItem 方法的延续?的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。