按钮点击调用异步方法 [英] Calling async method on button click

查看:1286
本文介绍了按钮点击调用异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆