2017-03-05 75 views
1

我有這個類:爲什麼我的程序在返回後會凍結?

public class ImgurAPI 
{ 
    private string ClientId = "id"; 
    private string ClientSecret = "secret"; 
    private string BasicUri = "https://api.imgur.com/3/"; 
    private HttpClient HttpClient = new HttpClient(); 
    public ImgurAPI() 
    { 
     HttpClient.DefaultRequestHeaders.Add("Authorization", "Client-ID " + ClientId); 
    } 

    private async Task<HttpContent> doRequest(string urlQuery) 
    { 
     HttpResponseMessage response = await HttpClient.GetAsync(urlQuery); 
     return response.Content; 
    } 
    public HttpContent getImages(string search, int minSizeX, int minSizeY, string imageType, int page) 
    { 
     var url = BasicUri + "gallery/search/top/" + page.ToString() + "/"; 
     url += "?q=" + search; 
     Task<HttpContent> task = doRequest(url); 
     return task.Result; 
    } 
} 

,我稱之爲是這樣的:

private void SearchImageClicked(object sender, RoutedEventArgs e) 
{ 
    HttpContent content = api.getImages(SearchBox.Text, 0, 0, "png", 1); 
    // other code here 
} 

但當getImages回報,我的程序凍結。我在return task.Result;上放置了一個斷點,它就在那裏。但我也在getImages調用之後放置了一個斷點,並且它不會到達那裏,我的程序會凍結,我必須終止進程才能停止。

這怎麼可能?

回答

5

這是因爲你混合同步和異步。這條線將導致死鎖:

return task.Result; 

doRequest,你使用await,捕捉當前的同步上下文(因爲你沒有指定ConfigureAwait(false)HttpClient.GetAsync(urlQuery)完成後,調度嘗試運行的延續。捕獲的情景,即在UI線程,但在UI線程已經忙於等待doRequest才能完成,因此無法執行在doRequest延續:。你有一個僵局

當您使用async/await,你應該使用它一路;你應該不是等待一個異步方法完成。在你的情況下,最簡單的修復方法是使getImages異步,並將消費代碼更改爲異步。

請參閱this article斯蒂芬·克利裏關於這個問題的更多細節。

1

當你打電話給task.Result你基本上強迫你的調用線程等待,直到其他線程完成。

Task.Result

1

無論您getImagesSearchImageClicked也必須async

public async Task<HttpContent> getImages(string search, int minSizeX, int minSizeY, string imageType, int page) 
{ 
    var url = BasicUri + "gallery/search/top/" + page.ToString() + "/"; 
    url += "?q=" + search; 
    return await doRequest(url); 
} 

private async void SearchImageClicked(object sender, RoutedEventArgs e) 
{ 
    HttpContent content = await api.getImages(SearchBox.Text, 0, 0, "png", 1); 
    // other code here 
} 
相關問題