[英]Windows Service Task - Polling Cancellation
我正在编写Windows服务,并发现了一个示例,该示例建议如下编写轮询Windows服务:
private void Poll()
{
CancellationToken cancellationPoll = ctsPoll.Token;
while (!cancellationPoll.WaitHandle.WaitOne(tsInterval))
{
PollDatabase();
// Occasionally check the cancellation state.
if (cancellationPoll.IsCancellationRequested)
{
break;
}
}
}
我对取消感到有些困惑,如果我同时需要cancelPoll.WaitHandle.WaitOne()和cancelPoll.IsCancellationRequested还是他们做着同样的事情,而只需要一个?
!cancellationPoll.WaitHandle.WaitOne(tsInterval)
可以确保轮询间隔,因此在tsIntetval
轮询之间至少要有tsIntetval
(+操作持续时间):
--tsInterval--|--operation--|--tsInterval--|...
如果您查看CancellationToken.WaitHandle
的文档,则会显示以下内容:
取消令牌时发出的WaitHandle信号。
因此,在您的情况下,操作cancellationPoll.IsCancellationRequested
就足够了,因为它之后没有任何内容。 但是想象一下这样的情况:
while (!cancellationPoll.WaitHandle.WaitOne(tsInterval))
{
//long operation A
if (cancellationPoll.IsCancellationRequested)
{
break;
}
//long operation B
if (cancellationPoll.IsCancellationRequested)
{
break;
}
//long operation C
}
在这种情况下,偶尔检查取消状态以避免长时间运行很有意义。
需要!cancellationPoll.WaitHandle.WaitOne(tsInterval)
,以便您不必一直等待。 WaitOne(tsInterval)
将返回,因为令牌取消了WaitOne(tsInterval)
令牌以使其取消或时间已用完。 如果令牌接收到取消信号,则WaitOne(tsInterval)
将返回true
然后结束循环。
例如,如果您要执行以下操作:
while(true)
{
// long operation
if (cancellationPoll.IsCancellationRequested)
{
break;
}
Thread.Sleep(tsInterval);
}
如果在线程被Thread.Sleep()
阻塞时要求取消,则整个操作直到Thread.Sleep()
完成并且if
语句进入下一个循环时才知道需要取消。
等待WaitHanlde
在这里是多余的,因为从结果的角度来看,它的作用与IsCancellationRequested
相同-指示请求取消(但执行方式略有不同)。 因此,对于您的情况,您可以选择单个方法: WaitHandle
或IsCancellationRequested
。 但是请记住, WaitHandle
是IDisposable
并且需要处理关联的CancellationTokenSource
。 如果您选择使用IsCancellationRequested
请不要忘记添加一个调用,该调用应该重新安排诸如Thread.Sleep
线程,以免过度利用CPU资源。 可以应用WaitHanlde
一种情况是,当您需要等待句柄并且想向这种等待引入取消语义时:
WaitHandle.WaitAny(new [] { handleToWait, cancellationHandle });
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.