如何等待webclient OpenReadAsync完成

Mah*_*der 3 c# webclient task-parallel-library async-await windows-phone-8.1

我正在使用WebClient从Windows Phone 8.1应用程序中下载一些来自互联网的东西.下面是我在我的应用程序中使用的示例代码 - 我在下面调用方法,但我的webclient没有等待完成读取操作并在OpenReadAsync调用后立即返回.

如何确保我的方法返回操作必须等到OpenReadCompleted事件完成后?我见过多个类似的问题,但找不到解决方案.

MyCustomObject externalObj;  // my custom object

private static void CheckNetworkFile()
{
    try
    {
        WebClient webClient = new WebClient();
        webClient.OpenReadCompleted += (s, e) =>
        {
          externalObj = myReadWebclientResponse(e.Result); // my custom method to read the response
        };

        webClient.OpenReadAsync(new Uri("http://externalURl.com/sample.xml", UriKind.Absolute));                
    }
    catch (Exception)
    {
      externalObj = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 11

我建议您使用.NET 4.5中引入WebClient.OpenReadTaskAsyncasync/await关键字组合.您需要将async关键字添加到方法中,使其返回a Task并建议使用Async后缀结束您的方法:

MyCustomObject externalObj;

private static async Task CheckNetworkFileAsync()
{
    try
    {
        WebClient webClient = new WebClient();

        Stream stream = await webClient.OpenReadTaskAsync(new Uri("http://externalURl.com/sample.xml", UriKind.Absolute));                
        externalObj = myReadWebclientResponse(stream);
    }
    catch (Exception)
    {
      externalObj = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

如你所说,WebClient.OpenReadTaskAsyncWP8.1不可用,所以让我们创建一个扩展方法,它将是:

public static class WebClientExtensions 
{
    public static Task<Stream> OpenReadTaskAsync(this WebClient client, Uri uri)
    {
       var tcs = new TaskCompletionSource<Stream>();

       OpenReadCompletedEventHandler openReadEventHandler = null;
       openReadEventHandler = (sender, args) => 
       {
          try 
          {
             tcs.SetResult(args.Result);
          } 
          catch (Exception e)
          {
             tcs.SetException(e);
          }
       };

       client.OpenReadCompleted += openReadEventHandler;
       client.OpenReadAsync(uri);

       return tcs.Task;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以在你的身上使用它了WebClient.

您可以在async-await wiki中找到很棒的阅读材料,只需在搜索栏中按该标签过滤即可.