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

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

问题描述

我创建了 Windows Phone 8.1 项目,我试图在按钮点击时运行 async 方法 GetResponse(string url) 并等待该方法完成,但方法永远不会完成.这是我的代码:

I created Windows Phone 8.1 project and I am trying to run async method GetResponse<T>(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() 上.

我将按钮单击方法更改为 async 并在 async 方法之前使用了 await 并且我得到了结果(await GetResponse<string>(url")).Task> 有什么问题?task = GetResponse(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.

我还看到您在 GetResponse 方法中混合了异步代码和同步代码.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(基于任务的异步模式")约定作为 Jon 说.

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天全站免登陆