Zé *_*los 10 c# task-parallel-library
除了最常见的调用TaskFactory.StartNew的形式,只有"action"参数(1)https://msdn.microsoft.com/en-us/library/dd321439 ( v= vs.110).aspx
我们还有一种方法可以接受额外的参数作为"取消令牌"(2)https://msdn.microsoft.com/en-us/library/dd988458.aspx
我的问题是,我们为什么要使用call(2)而不是call(1)?
我的意思是,如果我没有将取消令牌作为参数传递(因为可以从委托函数访问变量令牌),页面(2)的MSDN中的示例也可以工作.例如:
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var files = new List<Tuple<string, string, long, DateTime>>();
var t = Task.Factory.StartNew( () => { string dir = "C:\\Windows\\System32\\";
object obj = new Object();
if (Directory.Exists(dir)) {
Parallel.ForEach(Directory.GetFiles(dir),
f => {
if (token.IsCancellationRequested)
token.ThrowIfCancellationRequested();
var fi = new FileInfo(f);
lock(obj) {
files.Add(Tuple.Create(fi.Name, fi.DirectoryName, fi.Length, fi.LastWriteTimeUtc));
}
});
}
}
); //note that I removed the ", token" from here
tokenSource.Cancel();
Run Code Online (Sandbox Code Playgroud)
当我将取消令牌传递给Task.Factory.StartNew时,下面是否发生了什么?
谢谢
Sco*_*ain 10
会发生两件事.
Canceled状态.OperationCanceledException从任务内部引发a 并且该异常以相同的标记传递,StartNew则会导致返回的Task进入该Cancelled状态.如果与异常关联的令牌是不同的令牌,或者您未在任务中传递令牌,则将进入该Faulted状态.PS你不应该Task.Factory.StartNew在没有传入的情况下调用,TaskScheduler因为如果你不这样做,它很容易导致你在你希望在后台线程上运行的UI线程上运行代码.使用Task.Run(替代,除非你absoultely需要使用StartNew,Task.Run具有相同的CancellationToken行为StartNew.
| 归档时间: |
|
| 查看次数: |
1070 次 |
| 最近记录: |