Joe*_*nos 5 c# asp.net asp.net-mvc async-await
我仍在了解 .NET 4.5 的各种异步功能,并且遇到了一些有趣的事情。鉴于我的 MVC 控制器中的以下内容,执行 (1) 和 (2) 时我得到不同的结果
public ActionResult Index() {
var stuff = SomeExpensiveFunction();
return View(stuff);
}
private byte[] SomeExpensiveFunction() {
string url = "http://some-url.../";
// (1)
var wc = new WebClient();
return wc.DownloadDataTaskAsync(url).Result;
// (2)
var hc = new HttpClient();
return hc.GetAsync(url).Result.Content.ReadAsByteArrayAsync().Result;
}
Run Code Online (Sandbox Code Playgroud)
从表面上看,它们似乎是相同的 -WebClient.DownloadDataTaskAsync和HttpClient.GetAsync都是async返回Task. 版本WebClient返回,Task<byte[]>而HttpClient版本返回Task<HttpResponseMessage>,我必须从中挖掘字节,但我正在.Result以任何一种方式调用,我希望在离开函数之前完成。
对于(1),我得到一个带有 的黄屏An asynchronous operation cannot be started at this time...。使用(2),一切正常。
我可以更改整个堆栈并使用async控制器方法本身和SomeExpensiveFunction,并且一切正常。但我试图找出 (1) 或WebClient使用 MVC 时的一般情况是否存在根本性错误。有什么想法吗?
编辑:我知道在这个示例中我可以使用这些调用的同步版本,因为我并没有真正异步执行任何操作 - 这只是一个基于更大代码库的示例。
您已经与 ASP.NET 的 SynchronizationContext 发生冲突。为了使 WebClient 示例正常工作,您应该使整个控制器异步。尝试这个:
public async Task<ActionResult> IndexAsync() {
string url = "http://some-url.../";
using (var wc = new WebClient())
return View(await wc.DownloadDataTaskAsync(url));
}
Run Code Online (Sandbox Code Playgroud)
有关异步控制器的简介,请参阅http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4 ,以及http://www.tugberkugurlu.com/ archive/asynchronousnet-client-libraries-for-your-http-api-and-awareness-of-async-await-s-bad-effects用于解释 async/await 模式的死锁效果。
| 归档时间: |
|
| 查看次数: |
5446 次 |
| 最近记录: |