【问题标题】:Deadlock on await Result [duplicate]等待结果的死锁[重复]
【发布时间】:2018-03-03 21:19:24
【问题描述】:

ASP.NET MVC 应用程序分为三层。从第一层开始,我在第二层调用一个方法,在第三层调用我调用 Web 服务的方法。下面是代码。两个层(2 和 3)都在解决方案中添加为 Class Library

namespace Web.Controllers // Layer 1
{
    using Web.Services;
    // other usings...
    public class Controller1
    {
        [HttpPost]
        public JsonResult Search(SomeObject request)
        {
            Service service = new Service();
            var result = service.Search(request).Result;
        }  
    }
}

namespace Web.Service // Layer 2
{
    using Web.Library;
    // other usings...
    public class Service
    {
        public async Task<SomeType> SearchFlights(SomeObject requestModel)
        {
            SomeObjectReturn result = new SomeObjectReturn();

            Library library = new Library();
            var result = await library.Search(requestModel);
            return result;

        }
    }
}

namespace Web.Library // Layer 3
{
    public class Library
    {
        public async Task<SomeObjectReturn> Search(SomeObject request)
        { 
            // here I call Sabre service to get the result...
            SomeObjectReturn obj = new SomeObjectReturn();
            RestClient restClient = RestClientFactory.Create();
            IActivity activity = new InstaFlightsActivity(restClient, requestModel);
            Sabre.Library.Workflow.Workflow workflow = new Sabre.Library.Workflow.Workflow(activity);
            SharedContext sharedContext = await workflow.RunAsync();
            // map sharedContext to SomeObjectReturn
            return obj;
        }
    }
}

现在我不知道为什么await workflow.RunAsync 会出现死锁。我还在workflow.RunAsync 上尝试过.ConfigureAwait(false)。但无论如何,僵局正在产生。我不知道代码有什么问题。

顺便说一句,我在Controller 中进行了如下更改,我得到了结果。

public async Task<JsonResult> Search(SomeObject request) {...

而不是上面。

标签: c# .net async-await deadlock


【解决方案1】:

Result 的调用会产生死锁。一旦有了异步 API,就应该一直使用 async/await,否则可能会出现死锁。所以如果你改变你的控制器代码如下,问题就会消失。

[HttpPost]
public async Task<JsonResult> Search(SomeObject request)
{
    Service service = new Service();
    var result = await service.Search(request);
}  

【讨论】:

  • 问题中已经提到的OP是否相同
  • @Fabio,不,OP 使用 synchronous 方法和.Resultblock 同步上下文。这可以防止对await 的任何调用返回到该上下文,从而导致死锁。最好的解决方案让一切都异步到顶部。即使有人使用ConfigureAwait(false),这也可以避免死锁,但仍然会浪费线程
  • @PanagiotisKanavos,OP 的最后一句话:顺便说一句,我在 Controller 中进行了如下更改,我得到了结果。我认为 OP 期望得到一些解释
猜你喜欢
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多