gpt4 book ai didi

c# - Parallel.ForEach 中的迭代器在多个线程上运行

转载 作者:太空宇宙 更新时间:2023-11-03 15:15:19 24 4
gpt4 key购买 nike

我有一些代码在 Parallel.ForEach 循环中运行。循环中的代码是线程安全的,但我使用的迭代器(带有 yield return 的自定义方法)不是。看起来迭代器正在多个线程上运行,这可能会导致问题。

问题背景

迭代器包含对 NHibernate 的调用(虽然这完全是偶然的,正如您稍后会看到的那样),并且由于我在并行化代码时遇到问题,所以我在 NHibernate Profiler 中查看是否可以对这种情况有所了解。中途它开始报告“在多个线程中使用单个 session 可能是一个错误”。

现在,根据 NHibernate Profiler 的说法,有问题的代码在迭代器内部(因此它并没有试图在 Parallel.ForEach 操作的其他地方实现某些东西)。所以我添加了一些我自己的代码,以便我可以检测 NHibernate Profiler 是什么,我看到了同样的东西。

从多个线程调用迭代器方法 - 我认为这是不可能的,因为其他人似乎也这么认为,例如这另一个 SO 答案:https://stackoverflow.com/a/26553810/8152

问题的简化演示

为了演示这个问题(不需要我所有无关的 gubbins 处理 NHibernate 等)我写了一个简单的控制台应用程序来显示同样的问题:

public class Program
{
public static void Main(string[] args)
{
Parallel.ForEach(YieldedNumbers(), (n) => { Thread.Sleep(n); });
Console.WriteLine("Done!");
Console.ReadLine();
}

public static IEnumerable<int> YieldedNumbers()
{
Random rnd = new Random();
int lastKnownThread = Thread.CurrentThread.ManagedThreadId;
int detectedSwitches = 0;
for (int i = 0; i < 1000; i++)
{
int currentThread = Thread.CurrentThread.ManagedThreadId;
if (lastKnownThread != currentThread)
{
detectedSwitches++;
Console.WriteLine(
$"{detectedSwitches}: Last known thread ({lastKnownThread}) is not the same as the current thread ({currentThread}).");
lastKnownThread = currentThread;
}
yield return rnd.Next(100,250);
}
}
}

在我的测试运行中,线程在 1000 次迭代中切换了 157 到 174 次。 Sleep 模拟我的操作所花费的时间。

总结

如果 .NET 中实现的迭代器模式本质上不是线程安全的,为什么 Parallel.ForEach 会这样做?和;什么是能够以安全的方式(在一个线程上)获取迭代器当前公开的数据,然后在多个线程上处理它的好解决方案? (例如,有没有办法强制迭代器回到一个线程?或者迭代器也必须是线程安全的以及为每次迭代调用的操作?或者完全是其他一些解决方案?)

版本历史

  • 更新了摘要,希望能避免或减少我原来问题的 XY 问题。

最佳答案

Is there any way to force the iterator back onto one thread?

不,您必须显式处理多个线程调用迭代器的情况。在幕后,如果多个线程正在调用 IEnumerator.MoveNext(),迭代器将按照它被告知的程度继续前进。这里没有发生隐式同步。

@JonSkeet blogged a while back关于锁定迭代。尽管我必须说这对我来说看起来像是 XY 问题,但您是否应该从多个线程并行调用 NHibernate?它是上下文线程安全的吗?这些是您在使用线程安全迭代器之前应该考虑的问题。

关于c# - Parallel.ForEach 中的迭代器在多个线程上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39253715/

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