获取任务取消提示我可以获取任务操作执行过程中传递给Task构造函数的CancellationToken。大多数示例如下所示:CancellationTokenSourcects=newCancellationTokenSource();CancellationTokentoken=cts.Token;TaskmyTask=Task.Factory.StartNew(()=>{for(...){token.ThrowIfCancellationRequested();//for循环体。}},token);但是,如果我的操作不是lambda而是另一个类中的方法并且我无法直接访问令牌怎么办?是将令牌作为状态传递的唯一方法吗?但是如果我的操作不是lambda而是放在其他类中的方法并且我没有直接访问令牌怎么办?是将令牌作为状态传递的唯一方法吗?是的,在这种情况下,您需要将标记框作为状态传递,或者包装在您用作状态的其他类型中。但是,仅当您计划在方法中使用CancellationToken时才需要它。例如,如果需要调用token.ThrowIfCancellationRequested()。如果您只是使用令牌来阻止方法被分派,则没有必要。我可以获取在执行任务操作期间传递给任务构造函数的CancellationToken吗?不,您不能直接从Task对象获取它,不。但是如果我的操作不是lambda而是放在其他类中的方法并且我没有直接访问令牌怎么办?是将令牌作为状态传递的唯一方法吗?是的,这是两个选择。还有其他人。(可能不是包含列表。)您可以使用匿名方法关闭取消令牌您可以将其作为状态对象等传递给您保留在令牌上。您可以通过其他更大的范围将令牌公开为状态,即作为公共静态字段(在大多数情况下是不好的做法,但有时可能适用)正如其他答案所说,您可以将令牌作为参数传递给您的方法。但是,重要的是要记住您仍然想将它传递给任务。Task.Factory.StartNew(()=>YourMethod(token),token)。这确保:如果取消发生在任务执行之前,任务将不会运行(这是一个很好的优化)被调用方法抛出的OperationCanceledException正确地将任务转换为已取消状态有一个非常简单的解决方案:classCancelingTasks{privatestaticvoidFoo(CancellationTokentoken){while(true){token.ThrowIfCancellationRequested();线程.睡眠(100);控制台.Write(".");}}staticvoidMain(string[]args){CancellationTokenSourcesource=newCancellationTokenSource();CancellationTokentok=source.Token;tok.Register(()=>{Console.WriteLine("Cancelled.");});Taskt=newTask(()=>{Foo(tok);},tok);t.开始();控制台.ReadKey();来源.取消();来源.处置();Console.WriteLine("主程序完成,按任意键。");.ReadKey();您可以通过反射访问内部字段来获取CancellationToken。publicCancellationTokenGetCancellationToken(任务任务){objectm_contingentProperties=task.GetType().GetField("m_contingentProperties",BindingFlags.NonPublic|GetField("m_cancellationToken",BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Instance).GetValue(m_contingentProperties);return(CancellationToken)m_cancellationToken;}提示:你可以自己用ILSpy搜索这样的东西,我们查看Task类参考源码可以看到,取消令牌存放在一个内部类:ContingentPropertieshttps:///referencesource.microsoft.com/#mscorlib/system/threading/Tasks/Task.cs,90a9f91ddd80b5cc目的是避免访问这些属性,它们并不总是需要的。以上就是C#学习教程:获取任务取消提示分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注—internalclassContingentProperties{//AdditionalcontextinternalExecutionContextm_capturedContext;//运行任务的执行上下文,如果有的话。//完成字段(异常和事件)internalvolatileManualResetEventSlimm_completionEvent;//如果需要等待则延迟创建。内部易失性TaskExceptionHolderm_exceptionsHolder;//曲目有异常,/取消字段(token、注册、内部请求)internalCancellationTokenm_cancellationToken;//任务的取消标记,如果它有一个内部共享的m_cancellationRegistration;//Task使用取消令牌internal注册,因为intm_internalCreadthancellation;合法地----设置它。//育儿字段//#ofactivechildren+1(对于这个任务本身)。//用于确保所有孩子都做ne在此任务可以完成之前//额外计数有助于防止----执行最终状态转换//(即最后一个子任务或此任务本身是否应调用FinishStageTwo())internalvolatileintm_completionCountdown=1;//抛出异常的子任务列表(TCE不算在内),//但尚未被父任务等待,延迟初始化。内部易失列表m_exceptionalChildren;//////设置内部完成事件。///internalvoidSetCompleted(){varmres=m_completionEvent;if(mres!=null)mres.Set();}//////检查我们是否在构造期间注册了CT回调,并注销了它。///当我们知道注册不再有用时应该调用它。如果任务已成功完成///或出现异常,则特别来自Finish()。///internalvoidDeregisterCancellationCallback(){if(m_cancellationRegistration!=null){//针对从中抛出的ODE进行强化处理CTR。//由于在调用此//时任务已经进入最终状态,我们在这里所能做的就是抑制异常。尝试{m_cancellationRegistration.Value.Dispose();}catch(ObjectDisposedException){}m_cancellationRegistration=null;}}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
