【发布时间】:2012-06-18 10:37:28
【问题描述】:
我刚刚遇到以下行为:
for (var i = 0; i < 50; ++i) {
Task.Factory.StartNew(() => {
Debug.Print("Error: " + i.ToString());
});
}
将导致一系列“错误:x”,其中大部分 x 等于 50。
同样:
var a = "Before";
var task = new Task(() => Debug.Print("Using value: " + a));
a = "After";
task.Start();
将导致“使用值:之后”。
这显然意味着 lambda 表达式中的连接不会立即发生。在声明表达式时,如何在 lambda 表达式中使用外部变量的副本?以下不会更好(我承认这不一定是不连贯的):
var a = "Before";
var task = new Task(() => {
var a2 = a;
Debug.Print("Using value: " + a2);
});
a = "After";
task.Start();
【问题讨论】:
-
他们为什么要这样做?无论如何,它们都是异步的。
-
可能重复“循环中的 C# 捕获变量”stackoverflow.com/questions/271440/…
-
恕我直言,你最终在这里问了 2 个问题——“真正的”问题似乎在标题中(如何捕获值,以便任务在循环时在值上运行),但是那么问题的主体似乎集中在“为什么这些事情会导致意外的值”(闭包捕获的效果意味着它们都引用了同一个变量)。因此,您最终会得到大多数解释行为的答案,而不是回答您的“真实”问题(AFAICT :)
-
True James,实际上,在阅读了最初的 cmets 之后,我更改了我的问题标题以更好地反映我的观点。
标签: c# asynchronous lambda closures task-parallel-library