与新任务(操作,令牌)

时间:2016-08-02 13:29:29

标签: c# task action

简介 首先,我已经阅读了以下文章,我认为他们没有回答这个问题:

Cancellation token in Task constructor: why? What is the use of passing CancellationToken to Task Class constructor?

我很清楚令牌参数的用途是什么。

我的问题 我试图用内联注释来记录代码,让你知道我在哪里错过了这一切都在一起。

代码执行我想要它做的事情: - 每2秒写入控制台 - 10秒后停止

我的问题:“howDoIGetFilled”参数如何获取“token”参数的值。第二个参数用于Task实例本身,而不是正在使用的Action。 如果有任何不清楚的地方,请告诉我你想澄清的内容。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TaskDelegatePlayground
{
    class Program
    {
        static void Main(string[] args)
        {           
            var source = new CancellationTokenSource();
            var token = source.Token;

            Action<object> action = howDoIGetFilled => TestCancellationWithToken((CancellationToken)howDoIGetFilled);
            //I understand that this works, as you pass in the token and it gets passed to the "howDoIGetFilled" variable.
            //action(token);        
            //Wrong because it's "hardcoding" the token variable now but I don't understand how the above gets filled in.
            //Action<object> action = howDoIGetFilled => TestCancellationWithToken(token);
            var task = new Task(action, token);

            task.Start();
            Thread.Sleep(10000);

            //This should cancel the operation       
            Console.WriteLine("Cancelling");                 
            source.Cancel();

            Console.WriteLine("Ended, press any key to close the application.");
            Console.ReadKey();           
        }

        public static void TestCancellationWithToken(CancellationToken token)
        {
            //no intellisense here for token / source            
            while (true)
            {
                if (token.IsCancellationRequested)
                    break;

                Console.WriteLine("test");                     
                Thread.Sleep(2000);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

简答:

当在线程池中调用Task时,操作将被执行,并且取决于它是{ "name": "asd", "email": "test@attendize.website", "website": "esdfs", "comment": "qasdas", "dob": "08\/03\/2016" } Action,它将在有或没有Action<T>的情况下执行。你可以选择传入。

长答案:

object state查看reference source,这是调用它的方式:

Task

您可以点击参考来源,查找 /// <summary> /// The actual code which invokes the body of the task. This can be overriden in derived types. /// </summary> internal virtual void InnerInvoke() { // Invoke the delegate Contract.Assert(m_action != null, "Null action in InnerInvoke()"); var action = m_action as Action; if (action != null) { action(); return; } var actionWithState = m_action as Action<object>; if (actionWithState != null) { actionWithState(m_stateObject); return; } Contract.Assert(false, "Invalid m_action in Task"); } CancellationToken的路径。

但基本上,构造函数调用内部构造函数,而内部构造函数又调用action来设置TaskConstructorCorem_stateObject(两者都可以在调用操作时使用)。

m_action由方法InnerInvoke()调用,该方法在多个地方调用,但您明白了。

我找到了Execute()的路由,它来自执行工作项的线程池。

Execute

有趣的是,如果在任务排队之前取消令牌已被取消,则存在短路。