如何根据最佳实践在 C# 4 中创建异步方法?
考虑以下代码片段:
public static Task<string> 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<Stream>(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<string>(t =>
{
var t1 =
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null)
.ContinueWith<string>(t2 =>
{
var response = (HttpWebResponse)t2.Result;
var stream = response.GetResponseStream();
var buffer = new byte[response.ContentLength > 0 ? response.ContentLength : 0x100000];
var t3 = Task<int>.Factory.FromAsync(stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null, TaskCreationOptions.AttachedToParent)
.ContinueWith<string>(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 请求,以字符串形式从 Web 服务器返回结果,并尽可能高效。
- 您在上面的示例中发现了有关异步流的任何问题吗?
- 在此示例中,可以在 .ContinueWith() 中包含 .Wait() 吗?
- 您是否发现这种和平的代码存在任何其他问题(暂时保留异常处理)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果与异步相关的 C# 4.0 代码庞大且丑陋 - 它有可能正确实现。如果它又好又短,那么很可能不是;)
..不过,您可以通过在 WebRequest、Stream 类上创建扩展方法并清理主方法来使其看起来更有吸引力。
PS:我希望 C# 5.0 具有新的
async
关键字和 库即将发布。参考:http://msdn.microsoft.com/ zh-cn/vstudio/async.aspx
If async related C# 4.0 code is huge and ugly - there is a chance that it's implemented properly. If it's nice and short, then most likely it's not ;)
..though, you may get it look more attractive by creating extension methods on WebRequest, Stream classes and cleanup the main method.
P.S.: I hope C# 5.0 with it's new
async
keyword and library will be released soon.Reference: http://msdn.microsoft.com/en-us/vstudio/async.aspx
您认为等待是不必要的,这是正确的 - 结果将阻塞,直到结果准备好。
但是,更简单的方法是使用 ParallelExtensionsExtras 中提供的示例进行基础库。
他们为
WebClient
制作了扩展,它完全可以满足您的需求:您可以在 这篇关于 .NET 并行编程博客的文章< /a>.
You're correct in thinking that the Waits are unnecessary - Result will block until a result is ready.
However, an even easier way would be to base it off use the examples provided in the ParallelExtensionsExtras library.
They have made extensions for
WebClient
which do exactly what you're looking for:You can read more about it in this post on the Parallel Programming with .NET blog.