本文介绍了Task.WhenAny和SemaphoreSlim类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 WaitHandle.WaitAny Semaphore 时,如下所示:

When using WaitHandle.WaitAny and Semaphore class like the following:

var s1 = new Semaphore(1, 1);
var s2 = new Semaphore(1, 1);

var handles = new [] { s1, s2 };

var index = WaitHandle.WaitAny(handles);

handles[index].Release();

似乎可以保证 WaitHandle.WaitAny 只能获取一个信号量.

It seems guaranteed that only one semaphore is acquired by WaitHandle.WaitAny.

是否可以为异步(异步/等待)代码获得类似的行为?

Is it possible to obtain similar behavior for asynchronous (async/await) code?

推荐答案

我想不出内置解决方案.我会这样:

I cannot think of a built-in solution. I'd do it like this:

var s1 = new SemaphoreSlim(1, 1);
var s2 = new SemaphoreSlim(1, 1);

var waits = new [] { s1.WaitAsync(), s2.WaitAsync() };

var firstWait = await Task.WhenAny(waits);

//The wait is still running - perform compensation.
if (firstWait == waits[0])
 waits[1].ContinueWith(_ => s2.Release());
if (firstWait == waits[1])
 waits[0].ContinueWith(_ => s1.Release());

这同时获得了两个信号量,但立即释放了第二个信号量.这应该是等效的.我想不出不必要地获取信号量的负面后果(当然,除了表演).

This acquires both semaphores but it immediately releases the one that came second. This should be equivalent. I cannot think of a negative consequence of acquiring a semaphore needlessly (except performance of course).

这篇关于Task.WhenAny和SemaphoreSlim类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-03 12:50