11

我正在尝试使用CancellationToken.NET 框架中提供的机制编写一个支持取消的 LINQ 查询。但是,目前还不清楚将取消和 LINQ 结合起来的正确方法是什么。

使用 PLINQ,可以编写:

 var resultSequence = sourceSequence.AsParallel()
                                    .WithCancellation(cancellationToken)
                                    .Select(myExpensiveProjectionFunction)
                                    .ToList();

不幸的是,WithCancellation()它只适用于ParallelEnumerable- 所以它不能与普通的旧 LINQ 查询一起使用。当然,可以使用WithDegreeOfParallelism(1)将并行查询转换为顺序查询 - 但这显然是一个 hack:

 var resultSequence = sourceSequence.AsParallel()
                                    .WithDegreeOfParallelism(1)
                                    .WithCancellation(cancellationToken)
                                    .Select(myExpensiveProjectionFunction)
                                    .ToList();

我还想避免Task为此操作创建单独的,因为我需要在多个地方执行此操作,并且我需要能够控制此代码在某些情况下运行在哪个线程上。

那么,没有编写我自己的实现WithCancellation()- 是否有替代方案可以实现相同的目标?

4

1 回答 1

36

这种方法怎么样?

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;
        }
    }
}
于 2011-07-14T22:20:24.860 回答