2017-06-01 46 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不會。