【发布时间】:2018-06-26 22:45:09
【问题描述】:
假设我有一个通过 .net mongo 驱动程序调用 Mongodb 数据库的方法(下面提到的 Collection 对象是其 Api 的一部分):
public virtual Task<List<T>> GetAllAsync()
{
return Collection.Find(Filter.Empty).ToListAsync();
}
现在我有一个异步 asp.net 控制器,我想从中调用此方法。但是这个例子遇到了线程死锁问题,导致当前的 asp.net 线程挂起:
public class TestController : AsyncController
{
[HttpGet]
public async Task<ActionResult> TestAction()
{
var data = await GetAllAsync<Client>();
...
}
}
虽然这个例子运行良好:
public class TestController : AsyncController
{
[HttpGet]
public async Task<ActionResult> TestAction()
{
var data = await GetAllAsync<Client>().ConfigureAwait(false);
...
}
}
唯一的区别是后一个示例中的ConfigureAwait(false)。
在这种情况下我应该在任何地方添加这个ConfigureAwait(false),还是有更优雅的解决方案?
更新: 如果我从头开始创建 MVC 项目,相同的操作方法可以正常工作,不会陷入死锁问题。虽然如果我使用迁移到新 MVC 的旧 MVC 项目,死锁问题出现在第一个示例中。不知道这两者有什么区别,我打开 packaged.config 和 bin 目录并确保使用相同版本的 Microsoft.AspNet.*,C# 代码相同。唯一不同的是旧解决方案预装了 StructureMap 和 Cassette 之类的东西,可能是 web.config 中的一些不同设置也会影响控制器行为。
【问题讨论】:
-
你使用的是什么版本的 MVC?建议在更新的版本中停止使用
AsyncController,而是使用内置异步的Controller。即TestController : Controller。这可能是您混合上下文的问题。 stackoverflow.com/questions/13721571/… -
Microsoft.AspNet.Mvc = 5.2.3, Microsoft.AspNet.Razor = 3.2.3, .net 4.7 不幸的是,用 Controller 替换 AsyncController 并没有修复第一个示例。谢谢
标签: c# mongodb async-await asp.net-mvc-5.2