如何在Parallel.ForEachAsync中使用CancellationTokenSource

问题描述 投票:0回答:1

有这个处理程序:

public async Task<Result> Handle(MyQuery request, CancellationToken cancellationToken)
{
     var cancellationTokenSource = new CancellationTokenSource();

     await Parallel.ForEachAsync(myList, async (objectId, _) =>
     {
         var result = await _service.GetObject(objectId);

         if (result.Any())
         {
             cancellationTokenSource.Cancel();
         }
     });

     if (cancellationTokenSource.IsCancellationRequested) return Result.Fail("Error message.");

     return Result.Ok();
}

这可行,但想知道我在这里使用的

CancellationTokenSource
是否正确?

c# .net parallel.foreach cancellationtokensource
1个回答
1
投票

您仅使用

CancellationTokenSource
作为布尔变量,如果目标是在满足某些条件时取消批次,那么用法是完全错误的,您需要将令牌传递给
ForEachAsync
调用(并且最好处理取消令牌在身体里)。沿着这些思路:

try
{
    await Parallel.ForEachAsync(myList, cancellationTokenSource.Token, async (objectId, ct) =>
    {
        // pass cancellation token
        var result = await _service.GetObject(objectId, ct);

        if (result.Any())
        {
            cancellationTokenSource.Cancel();
        }
    });
}
catch (OperationCanceledException e)
{
    Result.Fail("Error message.");
}

正如 @Magnus 正确指出的那样 - 您还应该使用传递给

Handle
方法 (
CancellationToken cancellationToken
) 的取消令牌:

var cancellationTokenSource = 
    CancellationTokenSource.CreateLinkedToken(cancellationToken);
// ...

另请参阅:

© www.soinside.com 2019 - 2024. All rights reserved.