2017-09-22 11 views
0

ASP.NET MVC 응용 프로그램에는 세 개의 레이어가 있습니다. 첫 번째 레이어에서 두 번째 레이어에서 메서드를 호출하고 메서드를 호출하여 웹 서비스를 호출하는 세 번째 레이어에서 호출합니다. 아래는 코드입니다. 두 층 (2 및 3) 모두 용액 중에 Class Library으로서 첨가된다. await workflow.RunAsync에 교착 상태가 왜 교착 상태 대기 중 결과

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; 
     } 
    } 
} 

이제 나도 몰라. 나는 에 .ConfigureAwait(false)도 시도했다. 그러나 어쨌든 교착 상태가 발생하고 있습니다. 나는 그 코드에 무슨 문제가 있는지 알지 못한다.

나는 아래 Controller에서 변경 한 결과를 얻었다.

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

대신에.

+0

'.Resul'과'.Wait()'는 * blocking * 호출입니다. –

+0

_ 나는 코드에 무엇이 문제가 있는지 알지 못합니다. '.Result'를 사용하여 코드가 쓰레드가 hisself의 완료를 기다리고있는 상태에있게됩니다. 호출 메소드는 작업이 완료 될 때까지 대기합니다. 스레드는 완료 상태를 알리기 위해 스레드가 유휴 상태가 될 때까지 대기합니다. – Fabio

+0

두 가지 덧글 : 1. 모든'ASP.NET' 컨트롤러는'Controller' 또는'ApiController' (웹 API 인 경우)에서 상속해야합니다. 2. 모든 컨트롤러의 동작은'async Task'가되어야합니다. ' –

답변

1

Result을 호출하면 교착 상태가 발생합니다. 비동기 API를 사용하면 async/await으로 끝까지 가야합니다. 그렇지 않으면 교착 상태가 발생할 수 있습니다. 따라서 아래와 같이 컨트롤러 코드를 변경하면 문제가 사라집니다.

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

OP가 이미 질문에서 언급 한 것과 같습니까 – Fabio

+1

@Fabio, 아니요, OP는 동기화 * 메서드를 사용하고 동기화 컨텍스트를 차단하는'.Result'를 사용했습니다. 이렇게하면'await'에 대한 호출이 해당 컨텍스트로 돌아가는 것을 막아서 교착 상태를 방지 할 수 있습니다. 가장 좋은 해결책은 모든 것을 비동기로 만드는 것입니다. 'ConfigureAwait (false)'를 사용하더라도 교착 상태를 피할 수 있지만 스레드를 낭비합니다. –

+0

@PanagiotisKanavos, OP의 마지막 문장 : _BTW, 컨트롤러에서 아래와 같이 변경 했으므로 결과가 나타납니다 ._ 왜 그런지 설명해라. – Fabio