2015-07-31 16 views
10

Na początek, jest to dyskusja, jeśli ktokolwiek z was robi coś takiego jak anulowanie żądań w kontrolerach WebAPI (prawdopodobnie również w przypadku MVC).Asp.net WebAPI: Przerwane (anulowane) żądania

Co mam na myśli w szczególności, jest następujący scenariusz: Klient (przeglądarka zazwyczaj) uruchamia żądania, odlatuje lub jest bardziej ogólny, przerywa żądanie z dowolnego powodu. Teraz żądanie jest przerywane po stronie klienta i nie będzie dłużej brane pod uwagę. Ale po stronie serwera żądanie jest jeszcze wykonanie i zazwyczaj można robić 2 rzeczy szczególnie interesujący:

  • Nawiąż (ciężki) DB-Query
  • Zrób (ciężki) zgłoszenia serwisowego do innej usługi

Na koniec wszystko (przynajmniej jeśli jest to przynajmniej operacja odczytu bez efektów ubocznych).

Czy w takim przypadku ktoś obsługuje anulowanie trwającego zapytania/zgłoszenia serwisowego?

Wiem, że Token Anulowania może zostać przekazany w kontrolerze API (mimo że nie udało mi się go uruchomić, więc anulowanie było rzeczywiście wymagane przy przerywaniu pracy klienta). Ten token odwołujący się, teoretycznie, musiałby zostać przekazany do wszystkich niższych warstw, aby obsłużyć prawdopodobne anulowanie wywołań DB i usług.

+0

to może nie odpowiedzieć na twoje pytanie w pełni, ale spójrz na http://stackoverflow.com/questions/19010856/should-we-use-cancellationtoken-with-mvc-web-api-controllers – David

+0

Brzmi interesująco . Wygląda na to, że można go użyć jako parametru CancellationToken (to wiedziałem), a zwłaszcza, że ​​został on anulowany przez framework. – cmart

Odpowiedz

6

Podczas gdy w momencie pisania WebAPI nie obsługuje bezpośrednio anulowania, OWIN API absolutnie robi. Jeśli korzystasz z interfejsu WebAPI 2.0, będziesz mieć dostęp do OWIN i będziesz mógł uzyskać dostęp do kontekstu za pomocą obwolut Microsoft, korzystając z metody rozszerzenia GetOwinContext().

Dogodnie anulowanie jest propagowane przy użyciu wartości CancellationToken ujawnionej przez właściwość CallCancelled obiektu OwinRequest. Możesz umieścić to wszystko razem, aby uzyskać token wewnątrz metody kontrolera:

public async Task Get() 
{ 
    var cancellation = Request.GetOwinContext().Request.CallCancelled; 

    await database.FooAsync(cancellation); 
} 

To dość brzydkie. Będziesz musiał wykonać to wywołanie w każdej metodzie, która musi obsługiwać anulowanie i nie działa dobrze z proponowaną przyszłością, w której WebAPI da ci to CancellationToken. Zamiast tego, czy nie byłoby lepiej, gdybyśmy mogli wprowadzić ten parametr?

public async Task Get(CancellationToken cancellation) 
{ 
    await database.FooAsync(cancellation); 
} 

Aby to zrobić, można utworzyć parametr niestandardowy wiązania, które chwyta CancellationToken z kontekstu OWIN:

public class OwinCancellationTokenBinding : HttpParameterBinding 
{ 
    public OwinCancellationTokenBinding(HttpParameterDescriptor parameter) 
     : base(parameter) 
    { 
    } 

    public override Task ExecuteBindingAsync(
     ModelMetadataProvider metadataProvider, 
     HttpActionContext actionContext, 
     CancellationToken cancellationToken) 
    { 
     actionContext.ActionArguments[Descriptor.ParameterName] 
      = actionContext.Request.GetOwinContext().Request.CallCancelled; 

     return Task.FromResult<object>(null); 
    } 
} 

Aby to wykorzystać, można zarejestrować wiązanie z HttpConfiguration używając jego ParameterBindingRules kolekcji :

config.ParameterBindingRules.Add(p 
    => p.ParameterType == typeof(CancellationToken) 
    ? new OwinCancellationTokenBinding (p) 
    : null); 

Ta reguła pasuje do dowolnego parametru typu CancellationToken. Możesz tutaj utworzyć dowolną regułę, która będzie pasować do parametrów, które chcesz, aby ta wartość była przewidziana.

+1

Dziękujemy! Ale czy nie jest to obsługiwane po wyjęciu z pudełka?Kiedy parametr CancellationToken jest używany jako ostatni parametr, jest on ustawiany przez potok Webapi. referencyjny: https://books.google.at/books?id=FVMnCgAAQBAJ&pg=PA45&lpg=PA45&dq=cancellationtoken+parameter+asp.net+web+api&source=bl&ots=gcdA_GNuZh&sig=utOt1UGAEd8p7q8g2YmneI_2SNc&hl=de&sa=X&ved=0CCQQ6AEwAWoVChMI1ufg-vSFxwIVBY4sCh2YhA9U# v = onepage & q = cancellationtoken% 20parameter% 20asp.net% 20web% 20api & f = false (Mam nadzieję, że ten link działa) – cmart

+0

Potem wygląda na to, że pracuję nad starymi informacjami. –

+1

Cóż, twój pomysł został zrealizowany! Są naprawdę sprytni faceci, którzy myślą o tych tematach w Microsoft, bądźcie dumni! – cmart

Powiązane problemy