.NET反向信号量?

mpe*_*pen 23 .net c# multithreading semaphore

也许现在已经太晚了,但我想不出一个很好的方法来做到这一点.

我已经开始了一堆异步下载,我想等到它们都在程序终止之前完成.这让我相信我应该在下载开始时增加一些东西,并在它完成时减少它.但那我怎么等到计数再次为0

信号量以相反的方式工作,因为当没有可用资源时阻塞,而不是当它们全部可用时阻塞(当count为0而不是非零时为块).

Han*_*ant 14

查看本杂志文章中的CountdownLatch课程.

更新:现在由4.0版本的CountdownEvent类框架覆盖.

  • 从头到尾都是一篇相当棒的文章. (7认同)

Dzm*_*uba 10

在.NET 4中,为此目的有一种特殊类型CountdownEvent.

或者你可以像这样建立类似的东西:

const int workItemsCount = 10;
// Set remaining work items count to initial work items count
int remainingWorkItems = workItemsCount;

using (var countDownEvent = new ManualResetEvent(false))
{
    for (int i = 0; i < workItemsCount; i++)
    {
        ThreadPool.QueueUserWorkItem(delegate
                                        {
                                            // Work item body
                                            // At the end signal event
                                            if (Interlocked.Decrement(ref remainingWorkItems) == 0)
                                                countDownEvent.Set();
                                        });
    }
    // Wait for all work items to complete
    countDownEvent.WaitOne();
}
Run Code Online (Sandbox Code Playgroud)

  • 哎呀......在我尝试之前,`CountdownEvent`看起来很棒.它不会让你从0开始计数并增加它,因为它已经发出信号. (2认同)
  • @Mark我写了一个很小的扩展方法,如果当前计数为0,则调用`.Reset(1)`而不是`.AddCount()`.这应该可以解决问题. (2认同)

Ryt*_*mis 8

看起来像System.Threading.WaitHandle.WaitAll可能非常适合:

等待指定数组中的所有元素接收信号.