gpt4 book ai didi

c# - System.Threading.Tasks for 循环中的奇怪行为

转载 作者:行者123 更新时间:2023-11-30 15:33:30 27 4
gpt4 key购买 nike

我在 for 循环中创建 System.Threading.Tasks,然后在同一循环中运行 ContinueWith

int[,] referencedArray = new int[input.Length / 4, 5];
for (int i = 0; i <= input.Length/4; i += 2048)
{
int[,] res = new int[input.Length / 4, 5];
int[,] arrayToReference = new int[input.Length / 4, 5];
Array.Clear(arrayToReference, 0, arrayToReference.Length);
Array.Copy(input, i, arrayToReference, 0, input.Length / 4);
Task<Tuple<int[,], int>> test = Task.Factory.StartNew(() => addReferences(arrayToReference, i));
test.ContinueWith(t => { Array.Copy(t.Result.Item1, 0, referencedArray, t.Result.Item2, input.Length / 4); MessageBox.Show("yai", t.Result.Item2.ToString()); });
Array.Copy(res, 0, referencedArray, i, input.Length / 4);

addReference sbroutine 在哪里:

public Tuple<int[,],int> addReferences(int[,] input, int index)
{
for (int i = 0; i < 2048; i++)
{
for (int j = 0; j < i; j++)
{
if ((input[i, 0] == input[j, 0]) && (input[i, 1] == input[j, 1]) && (input[i, 2] == input[j, 2]) && (input[i, 3] == input[j, 3]))
{
input[i, 4] = (j - i);
}
}
}
}
return new Tuple<int[,],int>(input,index);
}

但是,我得到了非常奇怪的结果:

1.索引(在任务启动时从循环计数器生成)不知何故变得太大。我最初认为这是因为循环计数器已经超过其最大值,停止了循环,但是当 continueWith 执行时它使用了新值。但是,即使我在启动时将循环计数器的值作为 index 发送给任务,错误仍然存​​在。 编辑:已解决

我弄错了原来的计数

2.由于某种原因,实际完成的任务少于预期(例如,尽管预计将创建 85 个任务,但基于循环计数器最大值 160,000 除以迭代 2,048 = 78,只有 77 个弹出窗口出现) - 编辑 检查控制台,很明显循环计数器在突然停止之前上升到大约 157,696。

我真的对任务和线程感到困惑,所以如果你能提供任何真正有用的帮助 - 提前致谢。

编辑 我已经按照 Douglas 的建议进行了更改,这解决了我的第一个问题 - 我仍然停留在第二个问题上。

最佳答案

这可能无法完全解决您遇到的问题,但作为起点,您需要通过在匿名方法中引用循环计数器之前将循环计数器复制到内部变量来避免闭包问题:

for (int i = 0; i <= input.Length/4; i += 2048)
{
// ...
int iCopy = i;
var test = Task.Factory.StartNew(() => addReferences(arrayToReference, iCopy));
// ...
}

参见 Jon Skeet's answer (特别是链接的文章)解释为什么这是必要的。

编辑:关于您的第二个问题,我怀疑它可能与整数除法有关。您期望 85 次迭代的 input.Length 的值是多少?你说 174,000 除以 2,048 应该得到 85,但实际上它会得到 84,因为整数除法会导致结果被截断。

Edit2:您没有看到所有预期迭代的另一个原因可能是您的程序在没有等待任务(通常在后台线程上执行)的情况下终止去完成。检查等待任务是否解决了您的问题:

List<Task> tasks = new List<Task>();
for (int i = 0; i <= input.Length/4; i += 2048)
{
// ...
var test = Task.Factory.StartNew(() => addReferences(arrayToReference, iCopy));
tasks.Add(test);
// ...
}
Task.WaitAll(tasks);

关于c# - System.Threading.Tasks for 循环中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17487675/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com