我有这堂课:
-o
我称之为:
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;
调用之后还放了一个断点,它没有去那里,我的程序冻结了,我必须终止进程才能让它停止。
怎么可能?
答案 0 :(得分:5)
这是因为您正在混合同步和异步。这一行导致死锁:
return task.Result;
在doRequest
中,您正在使用await
,它会捕获当前的同步上下文(因为您没有指定ConfigureAwait(false)
。当HttpClient.GetAsync(urlQuery)
完成时,调度程序尝试在捕获的上下文上运行continuation,即在UI线程上运行。但是UI线程已经忙于等待doRequest
完成,因此doRequest
中的延续不能执行:你有僵局。
当你使用async/await
时,你应该一直使用它;你应该不同步等待异步方法完成。在您的情况下,最简单的解决方法是使getImages
异步,并将使用代码更改为异步。
有关此问题的详细信息,请参阅Stephen Cleary的this article。
答案 1 :(得分:1)
当你调用task.Result
时,你基本上强迫你的调用线程等到另一个线程完成。
请参阅Task.Result
答案 2 :(得分:1)
您的<ta-emp ng-model="empCode" ng-change="OnChange()"></ta-emp>
和getImages
也必须是SearchImageClicked
。
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);
}