c# - 参差不齐的任务数组 - 并发问题

标签 c# .net multithreading task-parallel-library task

我正在以这种方式定义一个交错的线程数组(这样每个线程都可以在自己的目录树上操作)

Task[][] threads = new Task[InstancesDir.Length][];
for (int i = 0; i < InstancesDir.Length; i++)
{
    threads[i] = new Task[InstancesDir[i].Length];
}
for (int i = 0; i < FilesDir.Length; i++)
{
    for (int j = 0; j < FilesDir[i].Length; j++)
    {
        threads[i][j] = Task.Run(() =>
        {
            Calculate(i, j, InstancesDir, FilesDir, PointSum);
        });
    }
    Task.WaitAll(threads[i]);
}

但是在计算中我总是得到 j >= FilesDir[i].Length 的值。我还检查了对象是否按值传递,数组除外。有什么解决方法可以解决这个问题,造成这种行为的原因是什么?

附言。引入共享锁可能有助于缓解并发问题,但我想知道这种行为的原因。

最佳答案

But in calculate i always get value of j >= FilesDir[i].Length

这不是并发问题,因为您的 for 循环是在单个线程上执行的。发生这种情况是因为 lambda 表达式正在关闭您的 ij 变量。此效果称为 Closure .

为了避免它,在将两个变量传递给 Task.Run 之前创建一个临时副本:

var tempJ = j;
var tempI = i;

threads[tempI][tempJ] = Task.Run(() =>
{
    Calculate(tempI, tempJ, InstancesDir, FilesDir, PointSum);
});

关于c# - 参差不齐的任务数组 - 并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28315016/

相关文章:

c# - 在 C# 中持续运行进程的最佳实践

c# - 如何在进程等待完成时显示加载控件?

c# - 如果先前已获取锁,如何使用 Monitor 类和对象锁来防止方法执行

c# - 如何在 C# 中为枚举类型应用 InterLocked.Exchange?

Winforms 在单独的线程中执行代码

java - Java 中处理列表时的多线程性能

c# - 索引频繁更新的FieldCache

使用属性时的 C# 歧义错误

c# - Json.Net:用于自定义命名的 JsonSerializer-Attribute

java - Java 中的线程和观察者模式