OWIN SelfHost Web Api - request cancellation - how is it done? Subject cancels?

Can someone point me to a resource that will help explain how the web api (in particular, using Owin Self Host ) handles request cancellation?

Here is the sequence of events that I observe:

  • someone makes get out of chrome
  • Api controller (across multiple layers) launches async SQL query
  • someone presses the X button in chrome (I donโ€™t know exactly what is going on in the socket for this)

What will happen next in Web Api ??

Some code was running in the controller, is the thread working with it working? If it was an asynchronous controller waiting for another task, does this task still have awaiter if it returns with an exception?

In context: I have an async controller waiting for a task (this is the only call site) that seems to throw an inconspicuous exception in some cases with an edge. I have not yet been able to isolate or re-produce :)

I found something called HttpResponse.ClientDisconnectedToken , but I donโ€™t know well what is supported in Owin Selfhost +, this is even a good thing to use for all custom cancellations.

+6
source share
2 answers

I dealt with this by throwing a System.OperationCanceledException in the user middleware that I registered before WebApi.

 public class ExceptionHanldingMiddleware : OwinMiddleware { public override async Task Invoke(IOwinContext context) { try { await Next.Invoke(context); } catch (OperationCanceledException) when (context.Request.CallCancelled.IsCancellationRequested) { //swallow user-agent cancelling request. _log.Trace($"client disconnected on request for: {context.Request.Path}."); } catch (Exception ex) { _log.Error(ex); context.Response.StatusCode = (int) HttpStatusCode.InternalServerError; context.Response.ReasonPhrase = "Internal Server Error"; } } } 
+2
source

As you stated that your async controller expects a Task that sometimes gets some kind of exception, I offer you the ContinueWith extension method for a task that can only be started when your task crashes, for example this:

 task.ContinueWith( t => logger.Error(t.Exception.Message, t.Exception); , TaskContinuationOptions.OnlyOnFaulted); 

This is the default mechanism for handling exceptions, and it will work in an OWIN application.

Secondly, with regard to cancellation: the task can be started using the CancellationToken structure, which can be used to cancel the task at run time. You can read more in the MSDN article .

HttpResponse.ClientDisconnectedToken used for situations when the client has been disconnected and the request should not be executed at execution.

You can use this token or create your own CancellationTokenSource , for example:

 var source = new CancellationTokenSource(); var token = source.Token; var task = Task.Factory.StartNew(() => { // Were we already canceled? ct.ThrowIfCancellationRequested(); var moreToDo = true; while (moreToDo) { // Poll on this property if you have to do // other cleanup before throwing. if (ct.IsCancellationRequested) { // Clean up here, then... ct.ThrowIfCancellationRequested(); } } }, token); 
0
source

Source: https://habr.com/ru/post/986772/


All Articles