访问已处理的闭包,但不使用()块

本文关键字:处理 闭包 访问 | 更新日期: 2023-09-27 18:26:41

我收到关于的警告

进入已处理的封闭

但我看不出这是如何在这个代码中发生的:

private BlockingCollection<PicInfo> listOfPicInfoObjectBC;
private List<PicInfo> CreatePicInfoObjects(List<string> pics)
{
    listOfPicInfoObjectBC = new BlockingCollection<PicInfo>();
    var cts = new CancellationTokenSource();
    try
    {
        var parallelOptions = new ParallelOptions 
        {
            CancellationToken = cts.Token, 
            MaxDegreeOfParallelism = 10
        };
        Parallel.ForEach(pics, parallelOptions, (pic, loopState) =>
        {
            ParalellizedCreatePicInfoObjects(pic);
            if (!cts.Token.IsCancellationRequested)
                ParalellizedCreatePicInfoObjects(pic);
            else
            {
                loopState.Stop();
                cts.Token.ThrowIfCancellationRequested();
            }
        });
    }
    catch (OperationCanceledException exp)
    {
        .......
    }
    finally
    {
        cts.Dispose();
    }
    return new List<PicInfo>(listOfPicInfoObjectBC);
}

我在其他SO帖子中也看到过这个警告,但他们都必须对using()块做一些事情(如果有意义的话),但我没有。

如果这个警告是正确的,怎么会在这里发生?

[编辑]忘了提这个警告发生在if (!cts.Token.IsCancellationRequested)cts.Token.ThrowIfCancellationRequested();行。

访问已处理的闭包,但不使用()块

如果这个警告是正确的,怎么会在这里发生?

编译器不知道Parallel.ForEach何时以及如何执行传递的委托。可以推断的是,您将一个对象传递给lambda,这会导致它在闭包中被捕获,因此它会警告您,该对象可能会在执行委托之前被释放,因为它正在finally块中被释放。

在这种特殊情况下,可以抑制警告,因为您知道Parallel.ForEach将导致立即调用委托。