1

I have scenario where User is able to abort the jQuery Ajax call, subsequently I want to Cancel MVC Request then Web API request and lastly the SQL procedure execution.

How do I chain the cancellation of request from the browser to MVC Application. The MVC application will now trigger a Web API request which will query the database. we want to cancel any subsequent queries through the whole leg of the process if the requested response is not received.

I googled and found cancellation token of task can help me but I am unable to figure out how to make it work.

looking for example/suggestions on how to implement this.

so far I have tried using Task.Factory.StartNew but its not waiting for results.


  var tcs = new TaskCompletionSource<JsonResult>();
            
            //comment this whole this is just used for testing   
             Task.Factory.StartNew(() =>
            {
                //Simulate work (usually from 3rd party code)  
                for (int i = 0; i < 100000; i++)
                   Console.WriteLine("value" + i);

             

                //execution never comes here till above for loop or          
                //may be long execution /computation get completed             
                if (token.IsCancellationRequested)
                    token.ThrowIfCancellationRequested();

                //Console.WriteLine("Task finished!");
            }, token);
            tcs.SetResult(Json(ringSearch, JsonRequestBehavior.AllowGet));
            return tcs.Task;


Kunal
  • 31
  • 4

1 Answers1

0

TLDR;

Simply pass the token to all layers that may need it, and in each layer check whether IsCancellationIsRequested is true.

Long... requires some thought across sessions and requests...

On the request side, you need to have some sort of key. This key could be a GUID or some other unique, munged ID associated with the request. This is quite literally the key to everything that a particular user may do soon. This key (string) must map back to a CancellationTokenSource. It can be stored in HttpContext.Session or some other ephemeral store associated back to your user.

This means a few things.

Start the (possibly cancellable) Web API request (Db access or whatever) as an awaitable task, and, using this keyed task (This should run in the backgound), immediately return a DELETE HTTP or POST response with the cancelled task's info (it wasn't clear from your question whether the operation was a delete or a modify... I'm wording this as a delete, but the principle should be the same).

With this key, you've got it in the session state, and you can pass it on through any other layers of your solution. For example, you can

  • delete or cancel the entity from the database
  • remove it from the database
  • trigger any other business rules.

This cancellation token can be propagated to any or all layers of your software solution (see: https://devblogs.microsoft.com/premier-developer/recommended-patterns-for-cancellationtoken/).

Cancellation is done, on demand, by the user or a system call; in your case that could be a simple button click. At that point, any calls on any threads that check for cancellation will cancel their operations (if you so code, and you should). Why/how? You literally pass this token through every layer as part of a constructor call or other method, and in every layer check to see if the operation is cancelled (cooperative) or skip the checks and handle OperationCancelledOperation.

Kit
  • 20,354
  • 4
  • 60
  • 103