异步链接阻止webapi调用

时间:2016-02-14 07:29:28

标签: c# asp.net-web-api async-await

我有一个流程: 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控制器调用时,异步版本永远不会返回响应,而同步版本工作正常。

1 个答案:

答案 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();          
}