我正在尝试使用.NET框架中提供的
CancellationToken
机制编写一个支持取消的LINQ查询.然而,目前还不清楚结合取消和LINQ的正确方法.
使用PLINQ,可以写:
var resultSequence = sourceSequence.AsParallel() .WithCancellation(cancellationToken) .Select(myExpensiveProjectionFunction) .ToList();
不幸的是,WithCancellation()
只适用于一个ParallelEnumerable,所以它不能与普通的老LINQ查询一起使用.当然,可以使用WithDegreeOfParallelism(1)
将并行查询转换为顺序查询 – 但这显然是一个黑客:
var resultSequence = sourceSequence.AsParallel() .WithDegreeOfParallelism(1) .WithCancellation(cancellationToken) .Select(myExpensiveProjectionFunction) .ToList();
我也想避免为这个操作创建一个单独的Task,因为我需要在几个地方这样做,我需要能够在某些实例中控制这个代码运行的线程.
所以,编写我自己实现的WithCancellation() – 有没有办法实现同样的事情?
解决方法
这个方法怎么样?
var resultSequence = sourceSequence.WithCancellation(cancellationToken) .Select(myExpensiveProjectionFunction) .ToList(); static class CancelExtention { public static IEnumerable<T> WithCancellation<T>(this IEnumerable<T> en,CancellationToken token) { foreach (var item in en) { token.ThrowIfCancellationRequested(); yield return item; } } }