按钮点击调用异步方法 [英] Calling async method on button click
问题描述
我创建的Windows Phone 8.1的项目,我想在按钮点击运行异步方法的GetResponse(字符串URL)和等待的方法来完成,但方法不会被整理。这里是我的code:
I created Windows Phone 8.1 project and I am trying to run async method GetResponse(string url) on button click and waiting for the method to finish, but method is never finishing. Here is my code:
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()。
It will hang on task.Wait().
我改变了我的按钮点击的方法来异步和所使用的异步方法之前等待,我得到的结果(等待的GetResponse&LT;串&GT;(URL)
)。什么是错的任务&LT;名单,LT;串GT;&GT;任务=&的GetResponse LT;串&GT;(URL)
?
我在做什么错了?
I changed my button click method to async and used await before the async method and I get the result(await GetResponse<string>("url")
). What is wrong with Task<List<string>> task = GetResponse<string>("url")
?
What am I doing wrong?
感谢您的帮助!
推荐答案
您是经典的死锁的牺牲品。 task.Wait()
或 task.Result
是造成僵局UI线程阻塞调用。
You're the victim of the classic deadlock. task.Wait()
or task.Result
is a blocking call in UI thread which causes the deadlock.
不要在UI线程阻塞 。从来没有做到这一点。只是期待着。
Don't block in the UI thread. Never do it. Just await it.
private async void Button_Click(object sender, RoutedEventArgs
{
var task = GetResponseAsync<MyObject>("my url");
var items = await task;
}
顺便说一句,你为什么抓住引发WebException
和投掷回来?这将是更好,如果你根本就没有抓住它。两者都是一样的。
Btw, why are you catching the WebException
and throwing it back? It would be better if you simply don't catch it. Both are same.
此外,我可以看到你混异步code与的GetResponse
方法内同步code。 StreamReader.ReadToEnd
是一个阻塞调用 - 您应该使用 StreamReader.ReadToEndAsync
。
Also I can see you're mixing the asynchronous code with synchronous code inside the GetResponse
method. StreamReader.ReadToEnd
is a blocking call --you should be using StreamReader.ReadToEndAsync
.
还可以使用异步后缀,以返回任务或异步遵循TAP方法(基于任务异步模式),约定的乔恩说。
Also use "Async" suffix to methods which returns a Task or asynchronous to follow the TAP("Task based Asynchronous Pattern") convention as Jon says.
您的方法应该是这个样子,当你解决了所有上述关切下面。
Your method should look something like the following when you've addressed all the above concerns.
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);
}
这篇关于按钮点击调用异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!