【发布时间】:2019-04-26 17:14:34
【问题描述】:
我有这段代码(简化)来处理 100 个不同并行线程上的参数数组,但是变量 x 和 y 在线程中使用时被线程内的循环更改。如果我用 1 个线程运行该函数,那么它就可以工作。
我还尝试将参数放入 ConcurrentBag 并使用 foreach 进行循环,但结果相同,参数在线程中混合。
List<Task> tasks = new List<Task>();
var listConcurentBag = new ConcurrentBag<int>();
int nThreadCount = 0;
for (x=0; x<1000; x++)
for (y=0; y<1000; y++)
{
int x1=x;
int y2=y;
Task t = Task.Run(() =>
{
int param1=x1;
int param2=y2;
// some calculations with param1 and param2
listConcurentBag.Add(result);
}); // tasks
tasks.Add(t);
nThreadCount++;
if (nThreadCount == 100) // after 100 threads started, wait
{
nThreadCount = 0;
Task.WaitAll(tasks.ToArray());
tasks.Clear();
}
}
【问题讨论】:
-
这是故意的,还是错误的?
for (y=0; x<1000; y++) -
@TheodorZoulias 这只是 stackoverflow 中的一个错字
-
您似乎无缘无故地在这里做了很多工作 - 任务默认使用线程池,因此即使您尝试缓冲 100 个任务,您也只能执行与线程池一样多的任务可以交付。进行这种缓冲并没有明显的执行或内存使用收益。
-
“变量 x 和 y 被线程内的循环更改,而在线程中使用” - 不在您提供的此代码中。如果您想要一个清晰直接的答案,您需要提供minimal reproducible example。
-
@Enigmativity 这种方法的性能提升非常明显!从 1 个线程到 120 个线程,性能提高了大约 1000%!
标签: c# .net multithreading thread-safety task