如何根据最佳实践在C#4中创建异步方法?

请考虑以下代码段:

public static Task FetchAsync() { string url = "http://www.example.com", message = "Hello World!"; var request = (HttpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Http.Post; return Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null) .ContinueWith(t => { var stream = t.Result; var data = Encoding.ASCII.GetBytes(message); Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, data, 0, data.Length, null, TaskCreationOptions.AttachedToParent) .ContinueWith(t2 => { stream.Close(); }); }) .ContinueWith(t => { var t1 = Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null) .ContinueWith(t2 => { var response = (HttpWebResponse)t2.Result; var stream = response.GetResponseStream(); var buffer = new byte[response.ContentLength > 0 ? response.ContentLength : 0x100000]; var t3 = Task.Factory.FromAsync(stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null, TaskCreationOptions.AttachedToParent) .ContinueWith(t4 => { stream.Close(); response.Close(); if (t4.Result < buffer.Length) { Array.Resize(ref buffer, t4.Result); } return Encoding.ASCII.GetString(buffer); }); t3.Wait(); return t3.Result; }); t1.Wait(); return t1.Result; }); } 

它应返回Task ,发送带有一些数据的HTTP POST请求,以字符串forms从webserver返回结果,并尽可能高效。

  • 您是否发现上述示例中有关异步流的任何问题?
  • 在这个例子中,将.Wait()放在.ContinueWith()中是否可以
  • 您是否看到这种代码安静的任何其他问题(暂时搁置exception处理)?

如果异步相关的C#4.0代码是巨大而丑陋的 – 它有可能正确实现。 如果它很好又短,那很可能不是;)

..虽然,你可以通过在WebRequest,Stream类上创建扩展方法并清理主方法来使它看起来更具吸引力。

PS :我希望C#5.0带有新的async关键字和库,很快就会发布。

参考 : http : //msdn.microsoft.com/en-us/vstudio/async.aspx

你认为Waits是不必要的是正确的 – 结果将阻塞直到结果准备好。


但是,更简单的方法是使用ParallelExtensionsExtras库中提供的示例。

他们为WebClient做了扩展,它完全符合您的要求:

 static Task FetchAsync() { string url = "http://www.example.com", message = "Hello World!"; return new WebClient().UploadStringTask(url, "POST", message); } 

您可以在这篇关于Parallel Programming with .NET博客的文章中阅读更多相关内容。