如何实现线程池的 QueueUserWorkItem 方法的延续?
生活随笔
收集整理的這篇文章主要介紹了
如何实现线程池的 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 方法的延续?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于PaddleOCR实现AI发票识别的
- 下一篇: Wow,一个免费、不怕打的评论插件!