我试图找出在这种情况下使用的SemaphoreSlim使用Wait和WaitAsync之间的区别:
private SemaphoreSlim semaphore = new SemaphoreSlim(1);
public async Task<string> Get()
{
// What's the difference between using Wait and WaitAsync here?
this.semaphore.Wait(); // await this.semaphore.WaitAsync()
string result;
try {
result = this.GetStringAsync();
}
finally {
this.semaphore.Release();
}
return result;
}
答案 0 :(得分:13)
如果您有异步方法 - 如果可能,您希望避免任何阻塞调用。 SemaphoreSlim.Wait()
是阻止通话。那么如果您使用Wait()
并且信号量目前不可用会发生什么?它会阻塞调用者,这对于异步方法来说是非常意想不到的事情:
// this will _block_ despite calling async method and using await
// until semaphore is available
var myTask = Get();
var myString = await Get(); // will block also
如果您使用WaitAsync
- 如果此时信号量不可用,则不会阻止来电者。
var myTask = Get();
// can continue with other things, even if semaphore is not available
此外,您应该注意与async \ await一起使用常规锁定机制。这样做之后:
result = await this.GetStringAsync();
你可能在await
之后的另一个线程上,这意味着当你试图释放你获得的锁时 - 它可能会失败,因为你试图不是从你获得它的同一个线程中释放它。请注意,这是 NOT 信号量的情况,因为它没有线程关联(与Monitor.Enter
,ReaderWriterLock
之类的其他此类构造不同)。
答案 1 :(得分:3)
不同之处在于Wait
会阻塞当前线程,直到释放信号量,而WaitAsync
则不会。