gpt4 book ai didi

c# - 在 Parallel.For 中修改方法局部变量。这有多线程安全?

转载 作者:行者123 更新时间:2023-11-30 13:46:01 27 4
gpt4 key购买 nike

我有这段代码:

int totalData = result.Data.Count;
int count = 0;
Parallel.ForEach(result.Data, data =>
{
try
{
EventRange importedEntity = ImportEntity(auxResult.EntityName, data);
count++;
EntityImported(importedEntity, count, totalData);
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});

EntityImported 是一个事件,应该说明已经处理了多少实体,以及我应该处理多少实体。我担心的是在 lambda 中递增计数的线程安全性,以及您建议采取哪些步骤来确保始终使用正确的计数变量值触发事件。

最佳答案

目前它根本不是线程安全的。

您可以改用 Interlocked.Increment(ref count),但通常最好为每个线程设置一个“本地”值,并在最后对它们求和.这样,除了分配要处理的项目外,您不需要任何类型的跨线程数据流。

Parallel.ForEach 重载了专为此目的而设计 - 请查看文档底部附近的示例,因为它所做的事情非常与您的代码相似。 (它维护一个本地计数,然后在最后对计数求和。)不幸的是,由于您需要在每次迭代中引发事件的方式,这对您的特定情况没有帮助 - 但通常这是更好的方法。

在这种情况下,您应该在事件引发代码中使用 Interlocked.Increment 的结果:

Parallel.ForEach(result.Data, data =>
{
try
{
EventRange importedEntity = ImportEntity(auxResult.EntityName, data);
int newCount = Interlocked.Increment(ref count);
EntityImported(importedEntity, newCount, totalData);
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});

这样一来,每个计数都会引发一个事件(所以一个是 0,一个是 1,一个是 2,等等)。

关于c# - 在 Parallel.For 中修改方法局部变量。这有多线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24039085/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com