【问题标题】:Async/Await with RestSharp in Windows Phone 8在 Windows Phone 8 中使用 RestSharp 进行异步/等待
【发布时间】:2014-06-27 10:08:35
【问题描述】:

我确实在互联网上搜索了这个,有适用于 Windows Phone 7 的解决方案,但它们不适用于 Windows Phone 8,所以请帮助我解决我做错了什么。我正在编写一个使用 Mashape 的 API 的 WP8 应用程序。我正在使用 RestSharp NuGet 包。这是我等待的 RestSharp 包的扩展方法。

public static class RestClientExtensions
{
    public static Task<IRestResponse> ExecuteTaskAsync(this RestClient @this, RestRequest request)
    {
        if (@this == null)
            throw new NullReferenceException();

        var tcs = new TaskCompletionSource<IRestResponse>();

        @this.ExecuteAsync(request, (response) =>
        {
            if (response.ErrorException != null)
                tcs.TrySetException(response.ErrorException);
            else
                tcs.TrySetResult(response);
        });

        return tcs.Task;
    }

    public static Task<T> ExecuteTaskAsync<T>(this RestClient @this, RestRequest request) where T : new()
    {
        if (@this == null)
            throw new NullReferenceException();

        var tcs = new TaskCompletionSource<T>();

        @this.ExecuteAsync<T>(request, (response) =>
        {
            if (response.ErrorException != null)
                tcs.TrySetException(response.ErrorException);
            else
                tcs.TrySetResult(response.Data);
        });

        return tcs.Task;
    }
}

这是调用它的函数。该函数位于 API.cs 类文件中。

public async Task<SendMessage> SendMessage(String phone, String msg, TextBox textBox)
{
    // Create a POST request with the required headers & parameters
    var request = new RestRequest("sendsms/{api}.json", Method.POST);
    request.AddUrlSegment("api", apiKey);
    request.AddHeader("X-Mashape-Key", "abcdefghixyz");
    request.AddParameter("msg", msg);
    request.AddParameter("phone", phone);

    var temp = await client.ExecuteTaskAsync<SendMessage>(request);
    return temp;
}

这终于是需要所有这些的 Page1.xaml.cs 文件了。

private void appBarButton_Send_Click(object sender, EventArgs e)
{
    Api api = new Api();
    SendMessage a = api.SendMessage(contactNumber, textBox_Message.Text, textBox_Message).Result;
    MessageBox.Show(a.message);
}

如果我在 SendMessage() 方法中直接调用 RestSharp .ExecuteAsync() 方法,它可以正常工作。如果我这样做,它会一直执行到等待条件,返回 tcs.Task,然后整个应用程序就会停止。它保持这种状态,没有任何变化。知道我做错了什么吗?

【问题讨论】:

  • 不要抛出NullReferenceException。改为抛出ArgumentNullException
  • @AntP 谢谢!我会记住这一点,但 NullReferenceException 只是这里的人们理解和帮助我的占位符:-)

标签: c# windows-phone-8 async-await restsharp


【解决方案1】:

我会尝试等待 SendMessage 的返回

 private async void appBarButton_Send_Click(object sender, EventArgs e)
  {
      Api api = new Api();
      SendMessage a = await api.SendMessage(contactNumber, textBox_Message.Text, textBox_Message);
      MessageBox.Show(a.message);
  }

【讨论】:

    【解决方案2】:

    您已经通过这段代码引入了 UI 线程死锁。 SendMessage() 方法中的 await 正在尝试将继续任务编组到调用上下文,即 UI 上下文。但是 UI 上下文已经被 SendMessage(...).Result 调用中的任务结果等待阻塞了。 1. 如果您不需要将可等待对象编组回调用上下文,则应始终对可等待对象使用 ConfigureAwait(false) 方法,以避免此类死锁。代码中唯一需要此封送处理的地方是按钮单击处理程序,因为您必须在此处与 UI 控件进行交互。 SendMessage() 方法应该如下所示: var temp = await client.ExecuteTaskAsync(request).ConfigureAwait(false); 2. 你不应该将 .Result 或 .Wait() 用于异步方法。这样做时,你会失去任何异步编程的感觉。始终使用 await 进行异步方法调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-21
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 2019-07-29
      相关资源
      最近更新 更多