当前位置: 首页 > 编程语言 > C#

CancellationTokenTimeoutDoesn'tWorkinTask.Run分享

时间:2023-04-10 21:57:12 C#

CancellationTokenTimeoutDoesn'tWorkinTask.Run好的,我的问题很简单。为什么这段代码不抛出TaskCancelledException?staticvoidMain(){varv=Task.Run(()=>{Thread.Sleep(1000);return10;},newCancellationTokenSource(500).Token.Result;控制台.WriteLine(v);//这输出10-而不是抛出错误。控制台.Read();}但这有效staticvoidMain(){varv=Task.Run(()=>{Thread.Sleep(1000);return10;},newCancellationToken(true).Token).Result;控制台.WriteLine(v);//这个抛出Console.Read();托管线程中的取消:取消是合作的,不会强制监听器。侦听器确定如何优雅地终止以响应取消请求。您尚未在Task.Run方法中编写任何代码来访问CancellationToken并实施取消-因此您实际上忽略了取消请求并运行完成。我想是因为您没有从CancellationToken对象调用ThrowIfCancellationRequested()方法。这样,您就忽略了取消任务的请求。你应该这样做:voidMain(){varct=newCancellationTokenSource(500).Token;varv=Task.Run(()=>{Thread.Sleep(1000);ct.ThrowIfCancellationRequested();return10;},ct).Result;控制台.WriteLine(v);//现在抛出TaskCanceledException。控制台.Read();代码的第二个变体有效,因为您已经将Canceled状态设置为true此案例初始化令牌。的确,如上所述:如果cancelled为真,则CanBeCanceled和IsCancellationRequested都将为真已请求取消,则将立即抛出exceptionTaskCanceledException,而不会实际启动任务。取消正在运行的任务和计划的任务是有区别的。调用Task.Run方法后,任务只是被调度,可能还没有执行。当您使用具有取消支持的Task.Run(...,CancellationToken)重载系列时,将在任务即将运行时检查取消标记。如果此时取消令牌将IsCancellationRequested设置为true,则会抛出TaskCanceledException类型的异常。该任务负责调用ThrowIfCancellationRequested方法,或者如果该任务已经在运行则简单地抛出OperationCanceledException。根据MSDN,这只是一种方便的方法:if(token.IsCancellationRequested)throwsnewOperationCanceledException(token);两种情况下都使用不同类型的异常:catch(TaskCanceledExceptionex){//任务在运行前被取消。}catch(OperationCanceledExceptionex){//任务在运行时被取消。}另请注意,TaskCanceledException派生自OperationCanceledException,因此对于OperationCanceledException类型只能有一个catch子句:catch(OperationCanceledExceptionex){if(exisTaskCanceledException)//任务在运行前被取消。//任务在运行时被取消。使用带有令牌的Task.Delay的另一个实现而不是Thread.Sleep。以上是C#学习教程:UsingCancellationTokentimeoutinTask.Rundoesnotwork。分享的所有内容,如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——staticvoidMain(string[]args){vartask=GetValueWithTimeout(1000);Console.WriteLine(task.Result);控制台.ReadLine();}staticasyncTaskGetValueWithTimeout(intmilliseconds){CancellationTokenSourcects=newCancellationTokenSource();CancellationTokentoken=cts.Tok;cts.CancelAfter(毫秒);token.ThrowIfCancellationRequested();varworkerTask=Task.Run(async()=>{awaitTask.Delay(3500,token);return10;},token);尝试{返回等待workerTask;}catch(OperationCanceledException){返回0;}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: