c# - 使用线程数组

标签 c# multithreading

我是线程的新手,所以这对您来说可能很简单,但我花了几个小时试图弄明白。

假设我有一个函数

public double Gain(List<int> lRelevantObsIndex, ushort uRelevantAttribute)

需要一些时间才能完成,但它是一个只读函数。

我有一个 ushort[] 值数组,我想获取达到 Gain 函数最小值的 ushort 值。

这是我到目前为止所得到的,但它不起作用:

lRelevantObsIndex 是只读索引。

lRelevantAttributes 是 ushort 值的列表。

        //Initialize the threads
        double[] aGains = new double[lRelevantAttributes.Count];
        Thread[] aThreads = new Thread[lRelevantAttributes.Count];
        for (int i = 0; i < lRelevantAttributes.Count; i++)
        {
            aThreads[i] = new Thread(() => aGains[i] = Gain(lRelevantObsIndex, lRelevantAttributes[i]));
            aThreads[i].Start();
        }

        //Join the threads
        for (int i = 0; i < lRelevantAttributes.Count; i++)
            aThreads[i].Join();

        //The easy part - find the minimum once all threads are done
        ushort uResult = 0;
        double dMinGain = UInt16.MaxValue;
        for (int i = 0; i < lRelevantAttributes.Count; i++)
        {
            if (aGains[i] < dMinGain)
            {
                dMinGain = aGains[i];
                uResult = lRelevantAttributes[i];
            }
        }

        return uResult;

我知道这是一个简单的多线程问题 - 但仍然需要您动动脑筋,因为我是新手。

最佳答案

这有点棘手:您的 for 循环在这里使用修改后的值(所谓的 access to modified closure )

for (int i = 0; i < lRelevantAttributes.Count; i++)
{
    aThreads[i] = new Thread(() => aGains[i] = Gain(lRelevantObsIndex, lRelevantAttributes[i]));
    aThreads[i].Start();
}

在线程启动时,i 在您的 lambda 中会有所不同,访问错误的项。按如下方式修改循环:

for (int ii = 0; ii < lRelevantAttributes.Count; ii++)
{
    var i = ii; // Now i is a temporary inside the loop, so its value will be captured instead
    aThreads[i] = new Thread(() => aGains[i] = Gain(lRelevantObsIndex, lRelevantAttributes[i]));
    aThreads[i].Start();
}

这将解决问题,因为 lambda 将在循环的每次迭代中捕获临时变量 i 的当前值。

关于c# - 使用线程数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20887676/

相关文章:

c# - 为什么 CreateFile 需要永远?

java - 为分配给线程池 java 的一组任务创建超时

python - 用于在 python 中预加载文件的线程缓冲区迭代器

.net - RabbitMQ、.NET 和多线程

c# - 从给定的字体名称获取字体文件

c# - 如何处置我的 DbContext?

c# - (无法)开始使用 Facebook C# SDK

c# - 将公式单元格应用于 DataGridview

c# - 来自封闭 block 的变量在匿名函数中变为空

c# - 为什么 lock(this) thread.sleep 不适用于 ASP.NET 线程?