11

CancellationToken.NET フレームワークで提供されるメカニズムを使用してキャンセルをサポートする 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()ことはできませんが、同じことを達成する代替手段はありますか?

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 に答える