![](/img/trans.png)
[英]CancellationToken not working with WaitForConnectionAsync
[英]CancellationToken not working with zero timeout
我有一个代码,它依赖于一个零超时的取消令牌来提前退出。 这是片段
using System;
using System.Threading;
namespace ConsoleApp2
{
class Program
{
void DoIdleWait(TimeSpan timeout, CancellationToken cancellationToken)
{
var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
linkedCancellationTokenSource.CancelAfter(timeout);
while (!linkedCancellationTokenSource.IsCancellationRequested)
{
Console.WriteLine("Waiting");
}
}
static void Main(string[] args)
{
var prog = new Program();
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(2));
prog.DoIdleWait(TimeSpan.Zero, cts.Token);
}
}
}
由于超时为零,我希望它不会进入 if 块,但它没有这样做。 知道为什么会这样吗? 另外,有什么方法可以实现我想要做的事情吗?
解释一下这个问题,
为什么,当您从具有注册超时的
CancellationTokenSource
创建链接的CancellationTokenSource
,然后将结果令牌源设置为零超时时,它不知道应该取消吗?
更多释义
毕竟,零是零,它应该知道它被取消了......
答案是,因为CancellationTokenSource.CancelAfter
尝试注册计时器回调,该回调尝试将分辨率设置为零毫秒,它不可能兑现..
因此,反过来,您将获得任何标准计时机制可以在不使用 CPU 旋转的情况下为您提供的最小分辨率,大约为 5+ 毫秒...
您的问题可能还有其他解决方案,但是,简而言之,您不能依靠0
秒超时通过IsCancellationRequested
立即确认。 你需要重新考虑你的问题。
CancellationTokenSource.CancelAfter
方法( 源代码)不包括对TimeSpan.Zero
值的特殊处理,因此将取消调度到具有零超时的Timer
的ThreadPool
。 这会导致竞争条件,同步while (!linkedCancellationTokenSource.IsCancellationRequested)
循环在大多数情况下获胜。 考虑到DoIdleWait
方法的实现不在您的控制之下,我能想到的唯一解决方案是,如果您知道超时为零,则不要调用此方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.