我一直在尝试并行计算,但是我对程序中发生的事情感到困惑。
我正在尝试复制XNA框架的一些功能。 我使用了组件样式的设置,并且我想通过在单独的任务中调用每个组件的
我在循环中更新调用的代码如下:
这个出现了奇怪的错误:
然而,当使用“Tasks”时,它们的x位置很快就会相互分离,但实际上它们应该是相同的。每个“engineComponent.Update(gameTime)”在每个更新周期中调用一次,并传递相同的“gameTime”对象。
在使用“tasks[i].RunSynchronously()”替换“tasks[i].Start()”时,程序按预期运行。
我知道以这种方式使用任务可能不是特别有效的编程实践,所以我的问题是出于好奇:为什么上述代码没有按照预期工作?我知道我错过了一些显而易见的东西,但我一直无法追踪具体哪里出了问题。
对于这个长问题,我表示歉意,感谢您的阅读;)
我正在尝试复制XNA框架的一些功能。 我使用了组件样式的设置,并且我想通过在单独的任务中调用每个组件的
Update
方法来使我的程序更加高效。 然而,显然我做错了什么。我在循环中更新调用的代码如下:
public void Update(GameTime gameTime)
{
Task[] tasks = new Task[engineComponents.Count];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task(() => engineComponents[i].Update(gameTime));
tasks[i].Start();
}
Task.WaitAll(tasks);
}
这个出现了奇怪的错误:
一个未经处理的类型为 'System.AggregateException' 的异常在 mscorlib.dll 中发生
内部异常提到了索引超出范围。
如果我改变
Task[] tasks = new Task[engineComponents.Count];
to
Task[] tasks = new Task[engineComponents.Count - 1];
如果这样做的话似乎是有效的(或者至少程序不会抛出异常),但是数组中没有足够的空间来存储所有组件。尽管如此,所有组件都会被更新,尽管 tasks
数组的空间不足以容纳它们。
然而,在游戏运行时作为参数传递的 gameTime
对象有些失控。我很难确定问题所在,但是我有两个组件都仅使用一个圆形的x位置进行移动。
x += (float)(gameTime.ElapsedGameTime.TotalSeconds * 10);
然而,当使用“Tasks”时,它们的x位置很快就会相互分离,但实际上它们应该是相同的。每个“engineComponent.Update(gameTime)”在每个更新周期中调用一次,并传递相同的“gameTime”对象。
在使用“tasks[i].RunSynchronously()”替换“tasks[i].Start()”时,程序按预期运行。
我知道以这种方式使用任务可能不是特别有效的编程实践,所以我的问题是出于好奇:为什么上述代码没有按照预期工作?我知道我错过了一些显而易见的东西,但我一直无法追踪具体哪里出了问题。
对于这个长问题,我表示歉意,感谢您的阅读;)
i
确实被捕获了,但捕获的是变量而不是值。 Lambda表达式永远不会捕获一个值,而总是捕获一个变量。这并不像 OP 可以“记住”去捕获i
值一样。 - Jon Skeet