Hey everyone!
I got a neat little fix for you.
Problem: CancellationToken not being cancelled upon request abort.
We stumbled upon this small bug whilst implementing a straight foward, basic MVC 5 application.
My co-worker pointed out that the following code, although valid and correct was not working as expected in MVC 5:
[Route("tools/test")]
[HttpGet]
public async Task Test(CancellationToken token)
{
var now = DateTime.Now;
while (DateTime.Now < now.AddMinutes(1))
{
if (token.IsCancellationRequested)
{
return Json(false);
}
await BotherGoogle(token).ConfigureAwait(false);
}
return Json(true);
}
private async Task BotherGoogle( CancellationToken token)
{
using (var httpClient = new HttpClient())
{
await httpClient.GetAsync("http://www.google.be", token).ConfigureAwait(false);
}
}
I would call this action from JavaScript and abort the XHR request on the client after 5 seconds:
function startTest() {
var xhr = $.get('@Url.Action("Test")', function(data) {
toastr.info(data);
});
toastr.info('Test started');
setTimeout(function() {
xhr.abort();
toastr.info('Test aborted');
}, 5000);
}
As soon as the request had been aborted on the client, it would take around +- 40 seconds before the cancellation token on the server was marked as cancelled.
A solution
A solution, pointed out by Muhammad Rehan Saeed on David Paquette’s blog here involved linking 2 cancellation tokens together so if one cancellation token gets cancelled, so would the linked ones: