如何实现线程池的 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,它具有强大的编排能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值