【发布时间】:2018-11-15 02:42:03
【问题描述】:
阅读帖子时,Starting Tasks In foreach Loop Uses Value of Last Item),标记的答案很有意义。作者创建了一个新变量 pathCopy 以在任务中使用。我的问题是,只有在使用 Task.ContinueWith() 时才需要这样做吗?
这是一个例子:
private void GetAuditFiles()
{
_auditFiles = new ConcurrentBag<AuditFile>();
var tasks = new List<Task>();
foreach (var auditFile in Directory.GetFiles(_properties.AuditFileOutputPath))
{
var taskfile = auditFile;
tasks.Add(Task.Factory.StartNew(() =>
{
var file = DeserializeProcessProperties<AuditFile>(File.ReadAllText(taskfile));
file.filename = Path.GetFileName(taskfile);
_auditFiles.Add(file);
}));
}
Task.WaitAll(tasks.ToArray());
}
我需要设置一个像“var taskfile = auditFile;”这样的变量吗?
注意:我使用的是 VS 2017 的更新版本及其 C# 编译器。
【问题讨论】:
-
与
ContinueWith无关。它确实与 C# 4 及更早版本的编译器有关。 2018年你真的用过这样的编译器吗? -
在闭包中使用变量后更改变量并且您不希望闭包观察该更改时,这是必要的。在不使用
ContinueWith的情况下,您是否正在这样做,如果不知道您是如何 做到这一点,我们就无法真正说出来。 -
@Damien_The_Unbeliever 在很多情况下,您最终会关闭从 2.0 到现在的任何 C# 版本中更改的变量。现在,在不同版本的语言中,可能使您陷入这种情况的因素可能会略有不同,但这绝不意味着这只是 C# 2-4 的问题。
-
我还要注意,答案中显示的
ContinueWith(但只是从问题中复制的)是损坏的代码,不应被复制。每个ContinueWith都是独立执行的,没有同步,它们都在更新一个共享变量。由于比赛,您可能会失去将其从true更改为false的商店。 -
致 OP - 您肯定已经阅读了答案中包含的 cmets 和 Eric Lippert 博客的链接,这些链接解释了为什么这个特定问题不再相关
标签: c# continuewith