简介 首先,我已经阅读了以下文章,我认为他们没有回答这个问题:
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);
}
}
}
}
答案 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
来设置TaskConstructorCore
和m_stateObject
(两者都可以在调用操作时使用)。
m_action
由方法InnerInvoke()
调用,该方法在多个地方调用,但您明白了。
我找到了Execute()
的路由,它来自执行工作项的线程池。
Execute
有趣的是,如果在任务排队之前取消令牌已被取消,则存在短路。