我是线程的新手,所以这对您来说可能很简单,但我花了几个小时试图弄明白。
假设我有一个函数
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/