Cancellation Token signal not being received by the application code

Michel Fornaris 0 Reputation points
2024-06-20T19:01:11.7333333+00:00

looks like there is a limitation as it can be read here

https://github.com/dotnet/aspnetcore/issues/20229#issuecomment-623289191
https://video2.skills-academy.com/en-us/answers/questions/391343/cancellationtoken-in-controller-endpoint-hosted-in

but is there anything that can be done? our api needs to cancel a long running query if the user for example navigates to another page or just abort the request from one of the api client (SPA)

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,337 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,394 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,561 questions
ASP.NET API
ASP.NET API
ASP.NET: A set of technologies in the .NET Framework for building web applications and XML web services.API: A software intermediary that allows two applications to interact with each other.
313 questions
Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
7,258 questions
{count} votes

4 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 60,201 Reputation points
    2024-06-21T21:34:40.5866667+00:00

    the main issue is that with http protocol, it is a request/response protocol with no cancel support. the server typically will not detect a closed socket until it sends a response. this does not help with a long running query. you can change to websocket or signal/r where you could add support for sending a cancel event on the same connection as the query request, and process cancel.


  2. SurferOnWww 2,326 Reputation points
    2024-06-22T01:16:34.5866667+00:00

    If your app is hosted by IIS with in-process hosting model the following article might help:

    Handling aborted requests in ASP.NET Core

    The IIS in-process hosting model means:

    image (1)

    Please read the following document:

    Differences between in-process and out-of-process hosting

    "The following characteristics apply when hosting in-process: Client disconnects are detected. The HttpContext.RequestAborted cancellation token is cancelled when the client disconnects."

    Cancellation by client includes (1) click X button on the browser, (2) depress Esc key on keyboard, or (3) abort when XMLHttpRequest is used:

    cancel

    Sample code:

    View

    @{
        ViewData["Title"] = "Cancel";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
     
    <h1>Cancel</h1>
     
    <input type="button" id="ajaxRequest" value="Ajax Request" />
    <br />
    <input type="button" id="abortButton" value="Abort" />
    <br />
    <div id="result"></div>
     
    @section Scripts {
        <script type="text/javascript">
            //<![CDATA[
     
            var xhr;
     
            $(function () {
                $('#ajaxRequest').on('click', function (e) {
                    xhr = $.ajax({
                        url: '/home/cancel',
                        method: 'get',
                    }).done(function (response) {
                        $("#result").empty;
                        $("#result").text(response);
                    }).fail(function (jqXHR, textStatus, errorThrown) {
                        $("#result").empty;
                        $("#result").text('textStatus: ' + textStatus +
                            ', errorThrown: ' + errorThrown);
                    });
                });
     
                $('#abortButton').on('click', function (e) {
                    if (xhr) {
                        xhr.abort();
                    }
                });
            });
            //]]>
        </script>
    }
    

    Controller / Action Method

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using MvcCore5App4.Models;
    using System.Diagnostics;
    using Microsoft.AspNetCore.Authorization;
    using System.Threading;
    using System.Threading.Tasks;
    using System;
    using Microsoft.AspNetCore.Identity;
    using MvcCore5App4.Data;
     
    namespace MvcCore5App4.Controllers
    {
        public class HomeController : Controller
        {
            private readonly ILogger<HomeController> _logger;
     
            public HomeController(ILogger<HomeController> logger)
            {
                _logger = logger;
            }
     
            // ・・・中略・・・
     
            public async Task<IActionResult> Cancel(CancellationToken token)
            {
                _logger.LogInformation($"start: {DateTime.Now:ss.fff}");
                await Task.Delay(5000, token);
                _logger.LogInformation($"end: {DateTime.Now:ss.fff}");
                return View();
            }
        }
    }
    

    Result of [Start Debugging] the above code shown on the Output of Visual Studio 2022:

    0711Output

    See "Start again - Cancelled" in which a client cancelled within 5 sec.

    0 comments No comments

  3. ajkuma 24,151 Reputation points Microsoft Employee
    2024-06-24T18:57:23.3466667+00:00

    @Michel Fornaris , Based on my understanding of the scenario - The Linux workers run Kestrel/YARP which does forward request cancellation. If your requirement fits, you may test your scenario on a Linux app.

    We have a Uservoice feedback: HttpRequest cannot be cancelled: HttpContext.RequestAborted CancellationToken doesn't work in Azure environment

    Checkout these article/blogs: A Heavy Lift: Bringing Kestrel + YARP to Azure App Services | A Heavy Lift: Bringing Kestrel + YARP to Azure App Services


    If the answer helped (pointed you in the right direction) > please click Accept Answer

    0 comments No comments

  4. Bruce (SqlWork.com) 60,201 Reputation points
    2024-06-27T22:00:06.9433333+00:00

    triggering the cancelation token is unreliable. see the protocol:

    https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination

    in the http protocol, there is no defined support for request cancel other than do it gracefully (preferable wait for response end). The implementation is left to each server and client.

    in azure you are accessing the website via several proxy servers. azure has firewall servers, routing servers, frontend balancing servers, and often the client side has its own firewall servers and routing servers. each of these servers have their own logic for handling an http request cancel. any one of these proxies can fail to pass the cancel to the actual webserver. as noted above, even running out of process in IIS loses the cancel.

    so to reliabily do what you want, you will need to change your code, and use websockets rather than http.

    0 comments No comments