Reputation: 3215
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
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
Upvotes: 7