2013-03-19 3 views
5

작업이 완료 될 때까지 대기을 기다리는 것으로 알고 있습니다. 그러나 실제로 그 의미가 혼란 스럽습니다.비동기 WebApi ActionFilterAttribute. 비동기 작업이 아직 보류 중일 때 완료된 비동기 모듈 또는 처리기

일을하지 않는 코드 :

public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
{ 
    if (actionExecutedContext.Response.Content != null) 
    { 
     var responseContent = await actionExecutedContext.Response.Content.ReadAsStringAsync(); 
     DoSomething(responseContent); 
    } 
} 

코드 작업 않는다는 것을 : 오류 메시지를

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 
{ 
    if (actionExecutedContext.Response.Content != null) 
    { 
     var responseContent = actionExecutedContext.Response.Content.ReadAsStringAsync().ContinueWith(
     task => 
     { 
      DoSomething(task.Result); 
     }); 
    } 
} 

분명히 비동기 모듈 또는 처리기 완료 동안 비동기 작업이 아직 보류 중입니다.은 비동기 호출이 완료되기를 기다리지 않고 대신 "메인"스레드가 계속 진행되었다는 것을 알려줍니다. 스레드가 계속 진행될 것이라고 예상했지만 현재 방법은 아닙니다. 스레드가 asp.net 스택으로 돌아와서 다른 작업을하고 asyncOperation() 작업이 완료 될 때까지 돌아올 것이라고 생각했습니다.

다른 장소에서도 기다리고 있습니다 (예 : 웹 서비스 응답을 기다리고 있습니다). 그리고 나는 비슷한 문제가 발생하지 않았습니다. 왜 IActionFilterAttribute가 다르게 동작하는지 궁금합니다. 실제로 웹 서비스 호출은 응답 내용을 문자열로 읽는 것보다 오래 걸릴 수 있습니다.

나를 계몽 할 수 있습니까? 나는 그 개념을 이해하지 못했다는 느낌을 가지고있다.

+0

동작 필터 (WebAPI가 아닌 MVC의 일부)는 비동기 작업을 지원하지 않습니다. 비동기 액션 필터가 필요한 경우 메시지 핸들러를 대신 사용해보십시오. 오, 그리고 여기에 투표하십시오 (http://aspnet.codeplex.com/workitem/9582). –

+0

이것은 WebAPI 질문이며 적절한 ActionFilterAttribute (System.Web.Http ...)를 사용하고 있습니다. 작동해야한다고 말하는가? :) – lapsus

+0

나는 본다. 이 경우 자신 만의 AsyncActionFilterAttribute를 정의하고 IActionFilter.ExecuteActionFilterAsync를 구현해야 할 것입니다. –

답변

6

void를 반환하는 메서드에 비동기 코드를 추가하는 것은 위험하고 실제로는 결코 수행하지 않는 것입니다. What's the difference between returning void and returning a Task?을 참조하십시오.

대신 작업을 반환하는 메서드를 재정의하거나 구현해야합니다. 이 경우 ActionFilterAttribute는 IHttpActionFilter가 제공하는 Task를 숨기므로 대신 IActionFilter (ExecuteActionFilterAsync)를 구현해야합니다. 코드를 속성으로 사용하려면 Attribute 클래스에서 파생되었는지 확인하십시오. 예를 들어

:

public class AsyncActionFilterAttribute : Attribute, IActionFilter 
{ 
    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) 
    { 
     HttpResponseMessage response = await continuation(); 
     DoSomething(response); 
     return response; 
    } 
} 
0

를 구현하는 대신

public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 

다음과 같이 OnActionExecuted 방법의 비동기 버전을 구현해야 :

public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) 

당신이 기다리고 사용할 수있는이 방법을 방법 및 행동 내부에 당신이 예상대로 될 것입니다.

희망이 도움이됩니다.