Is there a way to cancel background task made with HostingEnvironment.QueueBackgroundWorkItem
?
There is CancellationToken
which notifies if tasks was cancelled but how can i do it?
Refering to https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx
A successful cancellation involves the requesting code calling the CancellationTokenSource.Cancel method
OK. Where can i get access to CancellationTokenSource
?
After few trials i came up with the soulution:
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct);
var cancellationToken = linkedTokenSource.Token;
return Task.Factory.StartNew(() =>
{
// do stuff on background
}, cancellationToken);
});
Update:
Indeed, task is not needed. Thanks svick for bringing that up.
Here is a bit more detailed code sample without task.
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct);
// following is a dummy method, but you get the idea.
// StoreCancellationTokenSourceSoItCanBeUsedSomewhereElse(linkedTokenSource);
var cancellationToken = linkedTokenSource.Token;
try
{
while(true)
{
cancellationToken.ThrowIfCancellationRequested();
// do bg stuff
}
}
catch (OperationCanceledException ex)
{
// either token is in cancelled state
}
});
The signature of HostingEnvironment.QueueBackgroundWorkItem
is:
public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
This means that a work item gets access to a CancellationToken
. But I don't think that's useful in your case. From the documentation:
The provided CancellationToken will be signaled when the application is shutting down.
If you want to cancel the workItem
based on some other condition, you can use a separate CancellationToken
, which you create from a CancellationTokenSource
. For example, to cancel a work item if it doesn't start within 10 seconds:
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
HostingEnvironment.QueueBackgroundWorkItem(_ =>
{
cts.Token.ThrowIfCancellationRequested();
// the code of the work item goes here
});
This will technically still start the work item, even if the CancellationToken
is cancelled, but it won't do anything.
Note that cancellation is always cooperative. This means that if you have a long-running work item, and you want to cancel it in the middle of its execution, you will need to keep checking the CancellationToken
periodically.