2017-06-01 47 views
4

我试图找出是什么SemaphoreSlim使用等待和WaitAsync之间的差异,在这种情况下的使用:信号灯等待VS 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; 
} 
+2

与大多数其他'XXX'和'XXXAsync'方法之间的区别一样:一个区块,另一个区块产生线程。 –

回答

7

如果您有异步方法 - 如果可能,您希望避免任何阻止调用。 SemaphoreSlim.Wait()是一个阻塞呼叫。那么,如果您使用Wait()和信号量目前不可用,会发生什么?如果您使用WaitAsync

// this will _block_ despite calling async method and using await 
// until semaphore is available 
var myTask = Get(); 
var myString = await Get(); // will block also 

- 如果信号不可用的时刻也不会阻塞调用者:它会阻塞调用者,这是非常意外的事情异步方法。

var myTask = Get(); 
// can continue with other things, even if semaphore is not available 

此外,您还应该小心使用常规锁定机制以及async \ await。这样做了以后:

result = await this.GetStringAsync(); 

你可能会在await后另一个线程,当你尝试释放你获取了锁,这意味着 - 它可能会失败,因为你试图不从您获得相同的线程释放它。注意这是不是信号量的情况,因为它没有线程亲和力(不像其他这样的结构像Monitor.EnterReaderWriterLock等)。

+1

信号量不是线程仿射的,所以它们可以从任何线程获取/释放。虽然其他锁定机制是线程仿射的。 –

3

不同的是,Wait阻塞当前线程,直到信号被释放,而WaitAsync不会。