为什么我的程序在返回后会冻结?

Dim*_*lov 1 .net uwp

我有这门课:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我这样称呼:

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

但是当getImages返回时,我的程序会冻结.我放了一个断点, return task.Result;然后它去了.但是我也在getImages通话结束后设置了一个断点,它没有去那里,我的程序冻结了,我必须杀死进程才能让它停止.

怎么可能?

Tho*_*que 5

这是因为你混合同步和异步.此行导致死锁:

return task.Result;
Run Code Online (Sandbox Code Playgroud)

doRequest,您正在使用await,它捕获当前的同步上下文(因为您没有指定ConfigureAwait(false).HttpClient.GetAsync(urlQuery)完成后,调度程序尝试在捕获的上下文上运行延续,即在UI线程上.但UI线程已经忙于等待为了doRequest完成,所以继续doRequest执行不能执行:你有一个死锁.

当你使用时async/await,你应该一直使用它; 你应该同步等待异步方法来完成.在您的情况下,最简单的修复方法是getImages同步,并将使用代码更改为异步.

有关此问题的详细信息,请参阅Stephen Cleary 撰写的这篇文章.