我继承了一个包含很长项目列表的应用程序。
这花了几个小时来循环,所以我想我可以通过运行线程来优化它。
示例:
foreach (var d in data)
{
try
{
// do alot of logic, takes time
}
catch (Exception e)
{
// catch error
}
}
我以为我可以通过以下方式对其进行优化:
foreach (var d in data)
{
try
{
ExecutionMethodThread(d);
}
catch (Exception e)
{
}
}
private void ExecutionMethodThread(data d)
{
Thread thread = new Thread(() => MethodThread(d));
thread.Start();
thread.Join();
}
虽然当我在foreach循环中设置断点时,我仍然注意到它等待每个项目完成后再继续下一个。 这显然不是我想要的,因为我希望这个列表能够运行 通过循环,我会有多个项目有自己的线程simultaniosly。
我如何实现这一目标?
澄清:
循环开始
第一项启动一个线程并执行逻辑
第二项不等待第一项,获得自己的线程和执行 逻辑等
答案 0 :(得分:5)
你需要两个循环。在第一个循环中,您将创建所有线程,并启动它们。然后在第二个循环中,您将等待所有线程完成。
var threads = new List<Thread>();
foreach (var d in data)
{
Thread thread = new Thread(() => new MethodThread(d));
thread.Start();
threads.Add(thread);
}
foreach (var thread in threads)
{
try
{
thread.Join();
}
catch (Exception e)
{
// ...
}
}
然而,这种方法仍有一些缺点。如果您要处理一万个数据项,会发生什么?您将为每个数据项创建一个线程,即使并非所有线程都可以同时运行,这意味着您将不必要地消耗资源。有更简单的方法来实现同样的目标:
Parallel.ForEach(data, (datum) =>
{
try
{
// Do your logic
}
catch (Exception e)
{
// ...
}
});
C#将自动使用合理数量的线程,以匹配处理器上可用内核的数量。
警告这假设您的逻辑是线程安全的,可以并行执行。切换到Parallel.Foreach()或从Helper函数中移出Join()时要非常小心。