2015-12-17 23 views
3

我有一個使用異步網絡API /等待一路下跌:異步/ AWAIT僵局,而無需使用Task.Result

public class SampleController : ApiController 
{ 
    public async Task<IEnumerable<DocumentModel>> GetAll() 
    { 
     List<DocumentModel> modelItems = new List<DocumentModel>(); 

     var response = await SearchDocumentsAsync(); 
     var items = response.Results.ToList(); 
     foreach(var document in documents) 
     { 
      var model = new DocumentModel() 
      { 
       Id = document.Id, 
       Name = document.Name 
      }; 

      modelItems.Add(model); 
     } 

     return modelItems; 
    } 

    private Task<DocumentSearchResponse<Document>> SearchDocumentsAsync() 
    { 
     using (var searchClient = new SearchServiceClient(new SearchCredentials(searchServiceKey), searchServiceUri)) 
     using (var indexClient = searchClient.Indexes.GetClient(indexName)) 
     { 
      var parameters = new SearchParameters() 
      { 
       IncludeTotalResultCount = true 
      }; 

      // call the Azure Search service 
      return indexClient.Documents.SearchAsync<Document>(search.Term, parameters); 
     } 
    }  
} 

我不是調用堆棧使用.Wait().Result任何地方。這樣的代碼是否仍然有可能死鎖?當我調試此代碼時,我似乎正在體驗一個,但對於我的生活,我無法弄清楚爲什麼。

我已經使用郵遞員發送了幾個請求,有時迴應永遠不會回來。如果我在調試器中按下暫停按鈕,它將顯示一行綠色的線條,表示「這是當此線程從當前函數返回時要執行的下一個語句。」當我按下暫停按鈕時,代碼的位置並不一致,但似乎只要其中一個請求被阻止,其他請求就會被阻止。

上面的代碼能否死鎖?

+1

當您調試代碼時,執行何處停止?您還需要提供一個可以複製問題的完整示例,以便我們能夠提供解決方案。 – Servy

+2

也就是說,死鎖可能是由很多事情造成的,同步阻塞同步上下文,而異步操作試圖發佈延續到它只是一種導致死鎖的方法。還有很多其他的。 – Servy

+0

我提到它在停止的地方並不一致。我對上面的代碼更感興趣。上面的代碼中是否有任何事情會導致死鎖? – Dismissile

回答

5

SearchDocumentsAsync中,您立即從SearchAsync返回任務。

您應該等待此任務,以確保indexClientsearchClient在操作完成之前不會處理。這些正在處理的可能是引入僵局的東西。

+0

如果我更改代碼以在SearchDocumentsAsync方法中添加async/await而不是返回任務,但我刪除了使用語句並將它們置於ApiController.Dispose方法中,是否會遇到類似的問題? – Dismissile

+0

@Dismissile我不知道MVC是否足夠好,多個線程可以同時調用同一個'SearchDocumentsAsync'實例嗎?如果是的話,你可以在那裏遇到問題。但是如果只有一個線程同時訪問實例,那麼將創建移動到構造函數以及將該處置移動到類的Dispose()方法上應該沒問題。注意:如果您的方法不需要創建客戶端,則可能會在其他調用中引入不必要的開銷。 –

+0

@ScottChamberlain mvc中的每個請求都有自己的實例,所以它不是真的可能 – Dismissile