Как отменить 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 периодически.

Другие вопросы по тегам