Как отменить HostingEnvironment.QueueBackgroundWorkItem
Есть ли способ отменить фоновое задание, выполненное с HostingEnvironment.QueueBackgroundWorkItem
?
Есть CancellationToken
который уведомляет, если задачи были отменены, но как я могу это сделать? Ссылаясь на https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx
Успешная отмена включает в себя запрашивающий код, вызывающий метод CancellationTokenSource.Cancel
ХОРОШО. Где я могу получить доступ к CancellationTokenSource
?
2 ответа
После нескольких испытаний я придумала sulution:
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(ct);
var cancellationToken = linkedTokenSource.Token;
return Task.Factory.StartNew(() =>
{
// do stuff on background
}, cancellationToken);
});
Обновить:
Действительно, задача не нужна. Спасибо svick за то, что поднял это. Вот немного более подробный пример кода без задачи.
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
}
});
Подпись HostingEnvironment.QueueBackgroundWorkItem
является:
public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
Это означает, что рабочий элемент получает доступ к CancellationToken
, Но я не думаю, что это полезно в вашем случае. Из документации:
Предоставленный CancellationToken будет сигнализироваться при закрытии приложения.
Если вы хотите отменить workItem
на основании какого-либо другого условия, вы можете использовать отдельный CancellationToken
, который вы создаете из CancellationTokenSource
, Например, чтобы отменить рабочий элемент, если он не запускается в течение 10 секунд:
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
HostingEnvironment.QueueBackgroundWorkItem(_ =>
{
cts.Token.ThrowIfCancellationRequested();
// the code of the work item goes here
});
Технически это все же запустит рабочий элемент, даже если CancellationToken
отменен, но он ничего не сделает
Обратите внимание, что отмена всегда в сотрудничестве. Это означает, что если у вас есть длительный рабочий элемент, и вы хотите отменить его в середине его выполнения, вам нужно будет постоянно проверять CancellationToken
периодически.