使用异步操作运行同步代码
Posted
技术标签:
【中文标题】使用异步操作运行同步代码【英文标题】:Using an Async Action to Run Synchronous Code 【发布时间】:2012-03-26 12:09:46 【问题描述】:我有一个搜索操作,它有两个路径,一个是同步路径,它只返回一个简单的视图,另一个是异步路径,它异步执行搜索然后返回一个视图。两者都是 GET 请求,因此它们是同一操作的一部分。
问题是当我访问操作“localhost:XXXX/Home/Search”时,页面只是无限加载。使用 Fiddler,我可以看到请求永远不会返回。我已经对其进行了调试,它到达了最后一行代码,但是,请求再次没有完成。
我已将复制简化为以下内容:
public async Task<ActionResult> Search()
return View();
VS11 警告我代码将在没有等待的情况下同步运行,这很好,但请求没有完成。
这应该有效吗?还是我需要在这里做点别的?
编辑
这是面向 .NET 4.5 的 MVC 4。
编辑 2
对于那些在代码中看得更清楚的人,这就是我需要在异步操作中同步的原因:
public async Task<ActionResult> Search(string query = null)
if (string.IsNullOrWhiteSpace(query))
return View(new SearchViewModel()); // never loads
var model = await _someService.SearchAsync(query);
return View(model); // loads
【问题讨论】:
我认为这应该工作,但由于某种原因没有。由于它在内部抛出并捕获NullReferenceExcpetion
,我认为这是一个错误。
提示:如果您的操作方法返回 Task<T>
,请确保您继承自 AsyncController
,而不是 Controller
。
2@vcsjones,我试过了,但没有用。还有it shouldn't be necessary in MVC4.
@svick - 也许在测试版中已经改变了,但它是必需的。那我得做点修修补补了。
好问题,好研究。
【参考方案1】:
这是测试版中的一个已知错误。 To quote Stephen Toub:
简短的回答是 .NET 4.5 Beta 中的 ASP.NET MVC 中存在一个已知错误,当异步方法同步完成时会导致此问题。在修复可用之前,一个简单的解决方法是添加“await Task.Yield();”作为 async 方法的第一行,强制它异步完成。为了使其正常工作,您还需要确保您使用的是 .NET 4.5 中 ASP.NET 提供的新 SynchronizationContext,这意味着您有以下行:
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
在配置文件的 appSettings 部分中。
【讨论】:
以上是关于使用异步操作运行同步代码的主要内容,如果未能解决你的问题,请参考以下文章