将WebClient方法转换为async/await

Col*_*inE 35 c# async-await microsoft-metro

我有一些现有的代码,我移植到Windows 8 WinRT.代码从URL获取数据,异步调用传递的委托:

private void RequestData(string uri, Action<string> action)
{
  var client = new WebClient();
  client.DownloadStringCompleted += (s,e) => action(e.Result);
  client.DownloadStringAsync(new Uri(uri));
}
Run Code Online (Sandbox Code Playgroud)

转换为WinRT需要使用HttpClient和异步方法.我已经阅读了一些关于async/await的教程,但有点困惑.如何更改上述方法,但保留方法签名以避免更改我的代码?

Col*_*ron 84

private async void RequestData(string uri, Action<string> action)
{
    var client = new WebClient();
    string data = await client.DownloadStringTaskAsync(uri);
    action(data);
}
Run Code Online (Sandbox Code Playgroud)

请参阅:http://msdn.microsoft.com/en-us/library/hh194294.aspx

  • 快速说明一下:除非您正在执行激活并忘记请求,否则将返回类型更改为Task,否则调用线程将继续执行,无论您是否等待RequestData (6认同)
  • 最好使用私有异步Task而不是async void (4认同)
  • 注意:这里不要错过的重要事情是调用不同的方法:`DownloadString*TASK*Async` vs`XownloadStringAsync`.由于需要保留向后兼容性,因此需要将新方法添加到类中 (2认同)

Ste*_*ary 9

如何更改上述方法,但保留方法签名以避免更改我的代码?

最好的答案是"你没有".如果您使用async,请将其一直使用.

private async Task<string> RequestData(string uri)
{
  using (var client = new HttpClient())
  {
    return await client.GetStringAsync(uri);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • `async void`有一些问题.单元测试,一个.但最适用于这种情况的是它如何处理错误:HTTP下载的任何问题都会直接在`SynchronizationContext`上引发异常,而`async Task`允许更自然地处理异常(从`await`抛出). (2认同)

McG*_*gle 7

此示例之后,首先使用以下方法创建异步任务,然后使用await以下命令获取其结果:

Task<string> downloadStringTask = client.DownloadStringTaskAsync(new Uri(uri));
string result = await downloadStringTask;
Run Code Online (Sandbox Code Playgroud)


L.B*_*L.B 5

var client = new WebClient();
string page = await client.DownloadStringTaskAsync("url");
Run Code Online (Sandbox Code Playgroud)

或者

var client = new HttpClient();
string page = await client.GetStringAsync("url");
Run Code Online (Sandbox Code Playgroud)