C# 使用LINQ和CancellationToken的正确方法
我正在尝试使用.NET framework中提供的机制编写一个支持取消的LINQ查询。然而,目前还不清楚将取消和LINQ结合起来的正确方法是什么 使用PLINQ,可以编写:C# 使用LINQ和CancellationToken的正确方法,c#,.net,linq,parallel-processing,cancellation,C#,.net,Linq,Parallel Processing,Cancellation,我正在尝试使用.NET framework中提供的机制编写一个支持取消的LINQ查询。然而,目前还不清楚将取消和LINQ结合起来的正确方法是什么 使用PLINQ,可以编写: var resultSequence = sourceSequence.AsParallel() .WithCancellation(cancellationToken) .Sel
var resultSequence = sourceSequence.AsParallel()
.WithCancellation(cancellationToken)
.Select(myExpensiveProjectionFunction)
.ToList();
不幸的是,它只适用于可并行枚举的
——因此不能与普通的旧LINQ查询一起使用。当然,可以使用将并行查询转换为顺序查询,但这显然是一种黑客行为:
var resultSequence = sourceSequence.AsParallel()
.WithDegreeOfParallelism(1)
.WithCancellation(cancellationToken)
.Select(myExpensiveProjectionFunction)
.ToList();
我还希望避免为此操作创建单独的任务
,因为我需要在多个位置执行此操作,并且在某些情况下,我需要能够控制此代码在哪个线程上运行
那么,除了编写自己的
with cancellation()
实现之外,还有其他方法可以实现同样的效果吗?这种方法怎么样
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;
}
}
}
var resultSequence=sourceSequence.WithCancellation(cancellationToken)
.选择(myExpensiveProjectionFunction)
.ToList();
静态类扩展
{
公共静态IEnumerable with Cancellation(此IEnumerable en,CancellationToken令牌)
{
foreach(英语中的var项目)
{
token.ThrowIfCancellationRequested();
收益回报项目;
}
}
}
这实际上值得成为Connect上的一个功能请求。我不太清楚这是否有任何影响,或者这是否有效,或者是否可以与AsParallel()一起使用,但我喜欢这个解决方案的简单性,所以我决定升级。如果我将其更改为返回en.TakeWhile(p_item=>!token.iscancellationrequest)
会对性能产生任何影响吗?我知道这个问题很久以前就有了,但是仅仅使用aspallel().WithCancellation(cancellationToken)
并让它成为PLINQ有什么错?