我创建了Windows Phone 8.1项目,并尝试在按钮单击时运行异步方法GetResponse(string url),并等待该方法完成,但是该方法从未完成。这是我的代码:
private void Button_Click(object sender, RoutedEventArgs
{
Task<List<MyObject>> task = GetResponse<MyObject>("my url");
task.Wait();
var items = task.Result; //break point here
}
public static async Task<List<T>> GetResponse<T>(string url)
{
List<T> items = null;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
try
{
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = strReader.ReadToEnd();
items = JsonConvert.DeserializeObject<List<T>>(text);
}
catch (WebException)
{
throw;
}
return items;
}
它将挂在task.Wait()上。
我将按钮单击方法更改为异步,并在异步方法之前使用了await,然后得到了result(await GetResponse<string>("url")
)。有什么问题Task<List<string>> task = GetResponse<string>("url")
吗?我究竟做错了什么?
谢谢您的帮助!
您是经典僵局的受害者。task.Wait()
或是task.Result
导致死锁的UI线程中的阻塞调用。
不要阻塞UI线程。永远不要做。等待它。
private async void Button_Click(object sender, RoutedEventArgs
{
var task = GetResponseAsync<MyObject>("my url");
var items = await task;
}
顺便说一句,你为什么要抓住它WebException
并把它扔回去?如果您根本不了解它,那就更好了。两者都一样。
我还可以看到您在GetResponse
方法内部将异步代码与同步代码混合在一起。StreamReader.ReadToEnd
是一个阻止呼叫-您应该使用StreamReader.ReadToEndAsync
。
如Jon所说,还对返回Task或异步以遵循TAP(“基于任务的异步模式”)约定的方法使用“ Async”后缀。
解决以上所有问题后,您的方法应类似于以下内容。
public static async Task<List<T>> GetResponseAsync<T>(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = await strReader.ReadToEndAsync();
return JsonConvert.DeserializeObject<List<T>>(text);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句