2016-12-02 64 views
1

我從System.Net.HttpClient類派生實現處理令牌檢索和重新搜索的客戶端。客戶端使用所有必需的驗證參數進行初始化,並可能同時使用。在這種情況下,我需要防止客戶端請求多個令牌(針對不同的請求)。在異步方法中使用信號量會導致WPF調度程序線程死鎖嗎?

我不知道我的代碼是否會導致一個WPF應用程序死鎖如果用戶啓動調度線程上多個Web請求(因爲信號量是不可重入的,所以調度線程可能在等待被阻止在信號量上,並且如果分派器線程被阻塞,原始任務可能無法完成)。

public class ApiClient : HttpClient 
{ 
    public override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     if (_token == null) 
     { 
      await _semaphore.WaitAsync(cancellationToken); 
      try 
      { 
       if (_token == null) 
       { 
        // _token = await _tokenService.AcquireToken(xx,xx,xx); 
       } 
      } 
      finally 
      { 
       _semaphore.Release(); 
      } 
     } 
     else if (_token.IsExpired) 
     { 
      await _semaphore.WaitAsync(cancellationToken); 
      try 
      { 
       if (_token.IsExpired) 
       { 
        // _token = await _tokenService.RefreshToken(xx,xx,xx); 
       } 
      } 
      finally 
      { 
       _semaphore.Release(); 
      } 
     } 
     return await base.SendAsync(request, cancellationToken); 
    } 
} 
+1

當有兩個線程彼此等待時發生死鎖。所以基本上,如果你的Dispatcher線程等待Api線程(實際上正在發生)和Api線程等待來自Dispatcher線程的響應(這不應該是這樣),那麼你將會遇到死鎖。我不明白爲什麼在你的場景中會發生死鎖。如果請求太多,最糟糕的情況是超時,有些則無法及時完成。 – 3615

+0

但是,當使用信號量的同步Wait()方法時,我肯定會發生死鎖,是嗎? – Ehssan

+1

我不這麼認爲。如果您將使用Wait()而不是WaitAsync(),則關於死鎖的情況不應改變,除非Api線程以某種隱藏方式嘗試訪問Dispatcher線程。不同之處在於線程使用率更低效:如果信號量已滿,ApplicationPool Task不會返回到池,但會被阻塞等待。因此,當下一個請求將驅動被阻塞的線程將無法提供請求並創建新的線程。所以你會得到更多的線程。 – 3615

回答

0

調度線程可以同時在信號

這不能與你所示的代碼發生等待被阻止。它使用異步等待(await),所以線程不會被阻塞。

相關問題