我有一个流程: WebApi> ServiceFramework> DBLayer> MongoDB的 即可。
由于它是一个新的应用程序,我确保在所有层中从头开始异步。但是,当我的数据库层具有异步代码时,webapi永远不会得到回复。
API CONTROLLER
[HttpGet]
public IHttpActionResult GetAllRecords()
{
var result = FrameworkApi.GetRecords().Result;
return Ok(result);
}
以上通话> FRAMEWORK API
public async Task<List<Record>> GetRecords()
{
return await FrameworkDbApi.GetRecords();
}
以上通话&gt; DB FRAMEWORK API(调用MongoDB)
public async Task<List<Record>> GetRecords()
{
return await Task.Run(() =>
NoSqlDocumentClient.GetDefaultDatabase().Result.
GetCollection<Record>("record").AsQueryable().ToList());
//following Synchronous version works..but defeats the purpose
//return NoSqlDocumentClient.GetDefaultDatabase().Result
// .GetCollection<Record>("record").AsQueryable().ToList();
}
但是,当通过测试用例调用DBLayer或Framework中的操作时,我会得到结果。但是当通过WebApi控制器调用时,异步版本永远不会返回响应,而同步版本工作正常。
答案 0 :(得分:2)
但是当通过WebApi控制器调用时,异步版本永远不会 在同步版本正常工作时返回响应。
那是因为您的实际请求是死锁。当您通过具有SynchronizationContext的WebAPI调用该方法时,您将看到死锁,与您的测试相反,当测试运行正常时。这就是你shouldn't block on async code。
的原因你的调用链应该是这样的,以避免死锁(这就是它意味着去#34;一直异步&#34;:
[HttpGet]
public async Task<IHttpActionResult> GetAllRecordsAsync()
{
var result = await FrameworkApi.GetRecordsAsync();
return Ok(result);
}
public Task<List<Record>> GetRecordsAsync()
{
return FrameworkDbApi.GetRecordsAsync();
}
public async Task<List<Record>> GetRecordsAsync()
{
var result = await NoSqlDocumentClient.GetDefaultDatabase();
return result.GetCollection<Record>("record").AsQueryable().ToList();
}