I started my first project with asp.net core and razor pages. On a client request, a long running database operation will be started. Now i want to recognize, when the user leaves the website, so the database operation can be cancelled.
I've tried it with a cancellationToken, but it will never be cancelled.
public async Task<JsonResult> OnPostReadAsync([DataSourceRequest] DataSourceRequest request, CancellationToken cancellationToken)
{
var messages = await _logMessageService.GetLogMessagesAsync(request, cancellationToken);
return new JsonResult(messages.ToDataSourceResult(request));
}
The function get called by an Telerik Kendo UI Grid. Can you tell me, why the cancellation token don't get cancelled, or what other options I have to detect a abortion by the client?
Edit 1
I pass the Token through to this function call of a NpgsqlCommand:
var dataReader = await command.ExecuteReaderAsync(cancellationToken);
To cancel IO bound ie task which is running long , following is code that you can do which i got form the C# with CLR book.
Design extension method for task as below.
private static async Task<TResult> WithCancellation<TResult>(this Task<TResult> originalTask,
CancellationToken ct) {
// Create a Task that completes when the CancellationToken is canceled
var cancelTask = new TaskCompletionSource<Void>();
// When the CancellationToken is canceled, complete the Task
using (ct.Register(
t => ((TaskCompletionSource<Void>)t).TrySetResult(new Void()), cancelTask)) {
// Create a Task that completes when either the original or
// CancellationToken Task completes
Task any = await Task.WhenAny(originalTask, cancelTask.Task);
// If any Task completes due to CancellationToken, throw OperationCanceledException
if (any == cancelTask.Task) ct.ThrowIfCancellationRequested();
}
// await original task (synchronously); if it failed, awaiting it
// throws 1st inner exception instead of AggregateException
return await originalTask;
}
as given in following example code you can cancel it by using extension method designed above.
public static async Task Go() {
// Create a CancellationTokenSource that cancels itself after # milliseconds
var cts = new CancellationTokenSource(5000); // To cancel sooner, call cts.Cancel()
var ct = cts.Token;
try {
// I used Task.Delay for testing; replace this with another method that returns a Task
await Task.Delay(10000).WithCancellation(ct);
Console.WriteLine("Task completed");
}
catch (OperationCanceledException) {
Console.WriteLine("Task cancelled");
}
}
In this example cancellation done based on given time , but you can call cancellation by calling cancel method.
So I found the answer myself after some more research. The problem is a bug in IISExpress as mentioned here: https://github.com/aspnet/Mvc/issues/5239#issuecomment-323567952
I switched to Kestrel and now everything works as expected.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.