2013-03-19 8 views
5

Ich verstehe, warten Sie wartet für eine Aufgabe (eine erwartete) abzurunden. Aber ich bin verwirrt darüber, was das eigentlich bedeutet.Async WebApi ActionFilterAttribute. Ein asynchrones Modul oder eine asynchrone Prozedur, die ausgeführt wurde, während eine asynchrone Operation noch ausstehend war

Der Code, der nicht Arbeit:

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

Der Code, der tut Arbeit:

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

Offensichtlich ist die Fehlermeldung ein asynchrones Modul oder Handler abgeschlossen, während Eine asynchrone Operation stand noch aus. sagt mir, dass es kein Warten auf den Async-Aufruf zu vervollständigen gab, stattdessen wurde der "Haupt" -Thread fortgesetzt. Ich habe erwartet, dass der Thread fortgesetzt wird, aber nicht innerhalb der aktuellen Methode. Ich dachte, der Thread würde auf den asp.net-Stack zurückkehren und andere Arbeiten ausführen und zurückkehren, sobald die asyncOperation() -Operation abgeschlossen ist.

Ich benutze erwarten an anderen Orten auch - (z. B. Warten auf Web-Service-Antworten) - und ich habe nirgendwo ähnliche Probleme aufgetreten. Ich frage mich, warum sich das IActionFilterAttribute anders verhält. Tatsächlich nehmen meine Web-Service-Anrufe wahrscheinlich viel länger als das Lesen des Inhalts der Antwort in eine Zeichenfolge.

Kann mir bitte jemand aufklären? Ich habe das Gefühl, dass ich das Konzept nicht verstanden habe.

+0

Aktionsfilter (Teil von MVC, nicht WebAPI) unterstützen keine asynchronen Operationen. Wenn Sie einen asynchronen Aktionsfilter benötigen, versuchen Sie stattdessen, einen Nachrichtenhandler zu verwenden. Oh, und [hier abstimmen] (http://aspnet.codeplex.com/workitem/9582). –

+0

Dies ist eine WebAPI-Frage und ich verwende das richtige ActionFilterAttribute (System.Web.Http ...) - sagst du, es sollte funktionieren? :) – lapsus

+0

Ich sehe. In diesem Fall müssten Sie wahrscheinlich Ihr eigenes 'AsyncActionFilterAttribute' definieren und' IActionFilter.ExecuteActionFilterAsync' implementieren. –

Antwort

6

Das Hinzufügen von asynchronem Code zu einer Methode, die void zurückgibt, ist gefährlich und fast nie das, was Sie tatsächlich tun möchten. Siehe What's the difference between returning void and returning a Task?.

Stattdessen müssen Sie eine Methode überschreiben/implementieren, die eine Aufgabe zurückgibt. In diesem Fall blendet ActionFilterAttribute den von IHFTpActionFilter bereitgestellten Task aus, sodass Sie stattdessen IActionFilter (ExecuteActionFilterAsync) implementieren müssen. Wenn Sie Code als Attribut verwenden möchten, stellen Sie sicher, dass Sie auch von der Attributklasse abgeleitet sind.

Zum Beispiel:

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

Statt Umsetzung

public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 

Sie haben die Asynchron-Version von OnActionExecuted Methode zu implementieren, wie folgt:

public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) 

diese Weise können Sie erwarten können Innerhalb einer Methode und Verhalten wird so sein, wie Sie es erwartet haben.

Hoffe, das hilft.