Ryan
Ryan

Reputation: 3215

Is there a way in .NET core web API to cancel a call?

We have a .NET Framework front end that makes a call to a .NET Core web API to retrieve items to show to a user. If the user makes a call for many tens of thousands of items and then decides to cancel the request it can eat up resources continuing to fetch items that we know the user no longer wants retrieved. Is there a way in .NET, once the call has made it to the service, to cancel the call?

Upvotes: 3

Views: 2374

Answers (1)

Dude0001
Dude0001

Reputation: 3450

Look into CancellationTokens

In a sample Controller

public class SlowRequestController : Controller
{
    private readonly ILogger _logger;

    public SlowRequestController(ILogger<SlowRequestController> logger)
    {
        _logger = logger;
    }

    [HttpGet("/slowtest")]
    public async Task<string> Get()
    {
        _logger.LogInformation("Starting to do slow work");

        // slow async action, e.g. call external api
        await Task.Delay(10_000);

        var message = "Finished slow delay of 10 seconds.";

        _logger.LogInformation(message);

        return message;
    }
}

You could instead do this

public class SlowRequestController : Controller
{
    private readonly ILogger _logger;

    public SlowRequestController(ILogger<SlowRequestController> logger)
    {
        _logger = logger;
    }

    [HttpGet("/slowtest")]
    public async Task<string> Get(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Starting to do slow work");

        for(var i=0; i<10; i++)
        {
            cancellationToken.ThrowIfCancellationRequested();
            // slow non-cancellable work
            Thread.Sleep(1000);
        }
        var message = "Finished slow delay of 10 seconds.";

        _logger.LogInformation(message);

        return message;
    }
}

You don't mention what the front end looks like but you'll need some way to signal the cancel from the client request. An example might be.

var xhr = $.get("/api/slowtest", function(data){
  //show the data
});

//If the user navigates away from this page
xhr.abort()

Good examples here

https://andrewlock.net/using-cancellationtokens-in-asp-net-core-mvc-controllers/

And here

https://www.davepaquette.com/archive/2015/07/19/cancelling-long-running-queries-in-asp-net-mvc-and-web-api.aspx

Upvotes: 7

Related Questions