以下是创建模拟长时间运行流程的新任务的示例代码。该任务本身并没有太多内容,只是专注于取消功能。我正在使用取消令牌来取消任务,并且代码对我来说工作正常。
CancellationTokenSource CTS = new CancellationTokenSource();
Task<Boolean> PTask = new Task<Boolean>(() =>
{
while (true)
{
if (!CTS.Token.IsCancellationRequested)
{
Thread.Sleep(5000);
}
else { Console.WriteLine("Thread Cancelled");break; }
}
return true;
}, CTS.Token, TaskCreationOptions.None);
PTask.Start();
Console.WriteLine("Hit Enter to cancel the Secondary thread you have started");
Console.ReadLine();
CTS.Cancel();
System.Console.WriteLine(PTask.Result);
但我无法理解的一件事是令牌参数(CTS.Token
)正在传递给Task
构造函数。即使不将令牌传递给构造函数,我实际上也可以取消任务,那么传递参数的实际用途是什么。
下面是一个稍作修改的版本,无需令牌参数即可工作。
CancellationTokenSource CTS = new CancellationTokenSource();
Task<Boolean> PTask = new Task<Boolean>(() =>
{
while (true)
{
if (!CTS.Token.IsCancellationRequested)
{
Thread.Sleep(5000);
}
else
{
Console.WriteLine("Thread Cancelled");
break;
}
};
更新:
下列msdn http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/c2f614f6-c96c-4821-84cc-050b21aaee45问题描述了原因:
将令牌传递到 StartNew 会将令牌与任务关联起来。
这有两个主要好处:
-
如果令牌有取消
在任务开始执行之前请求,任务不会
执行。它不会立即转换为“运行”,而是会
过渡到已取消。这避免了运行任务的成本,如果
无论如何,它都会在运行时被取消。
-
如果身体的
任务还监视取消令牌并抛出
包含该标记的OperationCanceledException(这就是ThrowIfCancellationRequested
确实如此),那么当任务看到 OCE 时,
它检查 OCE 的令牌是否与任务的令牌匹配。如果它
确实如此,该例外被视为对合作的认可
取消并且任务转换到 Canceled 状态(而不是
比故障状态)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)