如何取消HostingEnvironment.QueueBackgroundWorkItem

时间:2016-05-14 10:27:38

标签: asp.net async-await cancellation-token

有没有办法取消使用HostingEnvironment.QueueBackgroundWorkItem制作的后台任务?

CancellationToken通知是否取消了任务但我该怎么办? 参考https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

  

成功取消涉及请求代码调用CancellationTokenSource.Cancel方法

行。我在哪里可以访问CancellationTokenSource

2 个答案:

答案 0 :(得分:3)

经过几次试验,我想出了洗液:

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
    }
});

答案 1 :(得分:1)

HostingEnvironment.QueueBackgroundWorkItem的签名是:

public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)

这意味着工作项可以访问CancellationToken。但我不认为这对你的情况有用。来自the documentation

  

当应用程序关闭时,将发出提供的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