c# - 单击按钮调用异步方法

标签 c# wpf multithreading windows-phone-8 asynchronous

我创建了 Windows Phone 8.1 项目并尝试运行 async方法 GetResponse<T>(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() 上.

我将按钮点击方法更改为 async并使用 awaitasync 之前方法,我得到结果(await GetResponse<string>("url"))。 Task<List<string>> task = GetResponse<string>("url")有什么问题? 我做错了什么?

感谢您的帮助!

最佳答案

您是经典僵局的受害者。 task.Wait()task.Result 是导致死锁的 UI 线程中的阻塞调用。

Don't block in the UI thread .永远不要这样做。只需等待即可。

private async void Button_Click(object sender, RoutedEventArgs 
{
      var task = GetResponseAsync<MyObject>("my url");
      var items = await task;
}

顺便说一句,为什么要捕获 WebException 并将其扔回去?如果你根本不捕获它会更好。两者相同。

我还看到您在 GetResponse 方法中将异步代码与同步代码混合在一起。 StreamReader.ReadToEnd 是一个阻塞调用——您应该使用 StreamReader.ReadToEndAsync

还对返回任务或异步的方法使用“Async”后缀,以遵循 TAP(“基于任务的异步模式”)约定,如 Jon says .

当您解决了上述所有问题后,您的方法应该如下所示。

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);
}

关于c# - 单击按钮调用异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28601678/

相关文章:

c# - 没有扩展名时 Application_BeginRequest 不触发

c# - WPF Richtextbox 以纯文本格式打开 RTF 文件

c# - IsChanged with IChangeTracking Not Firing on Window Close WPF MVVM C#

wpf - 如何设置分组框内子控件的字体?

java - Android:Asyctask异常问题

c# - 使用可选参数重载方法

c# - 为什么submit类型的按钮会触发父组件中的OnInit

c# - 为什么 AlternationIndex 为 ItemsControl 中的所有项目返回 0?

javascript - 我可以在单独的线程中运行 UIWebView 吗?

java - 结构如何正确通知其他线程有关事件的信息?