C# 访问已释放的闭包但不使用()块
我收到了关于你的警告 访问已处理的关闭 但我看不出在这段代码中是如何发生的:C# 访问已释放的闭包但不使用()块,c#,warnings,dispose,parallel.foreach,C#,Warnings,Dispose,Parallel.foreach,我收到了关于你的警告 访问已处理的关闭 但我看不出在这段代码中是如何发生的: private BlockingCollection<PicInfo> listOfPicInfoObjectBC; private List<PicInfo> CreatePicInfoObjects(List<string> pics) { listOfPicInfoObjectBC = new BlockingCollection<PicInfo>();
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);
}
private BlockingCollection listOfPicInfoObjectBC;
私有列表CreatePicInfoObjects(列表图片)
{
listOfPicInfoObjectBC=新建BlockingCollection();
var cts=新的CancellationTokenSource();
尝试
{
var parallelOptions=新的parallelOptions
{
CancellationToken=cts.Token,
MaxDegreeOfParallelism=10
};
Parallel.ForEach(pics,parallelOptions,(pic,loopState)=>
{
并行化CreatePicInfoObjects(pic);
如果(!cts.Token.IsCancellationRequested)
并行化CreatePicInfoObjects(pic);
其他的
{
loopState.Stop();
cts.Token.ThrowIfCancellationRequested();
}
});
}
捕获(操作取消异常扩展)
{
.......
}
最后
{
cts.Dispose();
}
返回新列表(listOfPicInfoObjectBC);
}
我在其他SO帖子中也看到过这个警告,但所有帖子都必须使用using()
块(如果有意义的话),但我没有
如果这个警告是正确的,它怎么会发生在这里
[编辑]
如果(!cts.Token.IsCancellationRequested)和cts.Token.throwifcCancellationRequested(),则忘记提及此上发生的警告代码>行
如果这个警告是正确的,它怎么会发生在这里
编译器不知道何时以及如何进行并行。ForEach
将执行传递的委托。可以推断的是,您将一个对象传递给lambda,这会导致它在闭包中被捕获,因此它会警告您,在执行委托之前可能会释放该对象,因为它在finally
块中被释放
在这种特殊情况下,警告可以被抑制,因为您知道,Parallel.ForEach
将导致立即调用委托。警告在哪里?无论如何,您可以忽略此警告,处理对象的唯一方法是在finally,这意味着,ForEach
中的lambda将不会被执行。确切地说,这个警告确实让我感到困惑。