什么是“cancellationToken”在TaskFactory.StartNew()中用于什么?

发布于 2024-09-19 08:01:52 字数 1787 浏览 3 评论 0原文

http://msdn.microsoft.com/en-us/library/dd988458.aspx

UPD

那么,让我们讨论这篇文章:http://msdn.microsoft.com/en-us/library/dd997396.aspx

我稍微更改了该代码:

    static void Main()
    {

        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            Thread.Sleep(5000);
            while (moreToDo)
            {

                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    Console.WriteLine("exit");
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }

            }
        }, tokenSource2.Token); // this parameter useless

        Console.WriteLine("sleep");
        Thread.Sleep(2000);
        Console.WriteLine("cancel");

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
            {
                Console.WriteLine(e.Message + " " + v.Message);
            }
        }

        Console.ReadKey();
    }

UPD:嗯,这仅更改task.IsCanceled,恕我直言,这是无用的,因为我仍然应该手动实现所有操作。

http://msdn.microsoft.com/en-us/library/dd988458.aspx

UPD:

so, let's discuss this article then: http://msdn.microsoft.com/en-us/library/dd997396.aspx

I've changed that code a little:

    static void Main()
    {

        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            Thread.Sleep(5000);
            while (moreToDo)
            {

                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    Console.WriteLine("exit");
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }

            }
        }, tokenSource2.Token); // this parameter useless

        Console.WriteLine("sleep");
        Thread.Sleep(2000);
        Console.WriteLine("cancel");

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
            {
                Console.WriteLine(e.Message + " " + v.Message);
            }
        }

        Console.ReadKey();
    }

UPD: Well, this changes only task.IsCanceled, which is imho useless, due to I still ought to implement all manually.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我做我的改变 2024-09-26 08:01:52

由于评论,我发布了另一个答案。

考虑以下代码:

var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;

tokenSource.Cancel(); 

var task = Task.Factory.StartNew(() =>
{    
  // Were we already canceled?
  ct.ThrowIfCancellationRequested();
  // do some processing
});

即使在任务实际启动之前调用 tokenSource.Cancel() ,您仍然会从线程池中分配一个工作线程,因此您会浪费一些系统资源。

但是,当您在 Task.Factory.StartNew 中指定 token 参数时,任务将立即取消,而不分配工作线程。

Due to comments, I'm posting another answer.

Consider the following code:

var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;

tokenSource.Cancel(); 

var task = Task.Factory.StartNew(() =>
{    
  // Were we already canceled?
  ct.ThrowIfCancellationRequested();
  // do some processing
});

Even if the call tokenSource.Cancel() is issued before the task was actually started, you'll still allocate a worker thread from thread pool, so you'll waste some system resources.

But when you specify token argument in Task.Factory.StartNew, the task will be cancelled immediately, without allocating a worker thread.

埖埖迣鎅 2024-09-26 08:01:52

取消任务仍然是合作的。您不希望线程在某些关键操作中被终止。你需要检查一下。

CancellationTokens 比诸如 ManualResetEvent 之类的更简单的结构更好,因为您可以级联或组合它们,例如,您可以将它们用于整个应用程序关闭,也可以将其与一个用于取消的组合一项特定任务。该任务只需查看一个 CancellationToken,但您可以从任一 CancellationTokenSource 取消它。

Cancellation with Tasks is still cooperative. You wouldn't want a thread to be killed in the middle of some critical operation. You need to check for it.

CancellationTokens are better than simpler constructs like a ManualResetEvent for signalling shutdown of an operation because you can cascade or combine them, for example, you can have one for overall application shutdown and you can combine it with one for canceling a particular task. The task only has to look at the one CancellationToken but you can cancel it from either CancellationTokenSource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文