6

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

如果任务被取消,有CancellationToken哪些通知,但我该怎么做?参考https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

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

好的。我在哪里可以访问CancellationTokenSource

4

2 回答 2

4

经过几次试验,我想出了解决方案:

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
    }
});
于 2016-05-14T11:44:39.337 回答
2

的签名HostingEnvironment.QueueBackgroundWorkItem是:

public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)

这意味着工作项可以访问CancellationToken. 但我认为这对你的情况没有用。从文档中

提供的 CancellationToken 将在应用程序关闭时发出信号。

如果要workItem根据其他条件取消 ,可以使用CancellationTokenCancellationTokenSource. 例如,如果工作项未在 10 秒内启动,则取消它:

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));

HostingEnvironment.QueueBackgroundWorkItem(_ =>
{
    cts.Token.ThrowIfCancellationRequested();

    // the code of the work item goes here
});

这在技术上仍然会启动工作项,即使CancellationToken被取消,但它不会做任何事情。

请注意,取消始终是合作的。这意味着如果您有一个长时间运行的工作项,并且您想在其执行过程中取消它,您将需要CancellationToken定期检查。

于 2016-05-14T11:45:50.753 回答