Iva*_* P. 8 .net c# multithreading task
任何人都可以解释为什么这个片段:
// Create required tasks
foreach (var messageToSend in messagesToSend)
{
EmailMessage messageToBeSent = messageToSend;
Task<bool> processingTask = new Task<bool>(() => SendMessage(messageToBeSent));
processingTask.Start();
}
Run Code Online (Sandbox Code Playgroud)
与此不同的是:
// Create required tasks
foreach (var messageToSend in messagesToSend)
{
Task<bool> processingTask = new Task<bool>(() => SendMessage(messageToSend));
processingTask.Start();
}
Run Code Online (Sandbox Code Playgroud)
在第一个片段中,所有任务都以自己的消息开头,而在第二个片段中,所有任务都以相同的消息开头?
Resharper给出了这样的描述:"在关闭时访问foreach变量.使用不同版本的编译器编译时可能会有不同的行为." 为什么它会有不同的行为?
Ant*_*ram 16
Resharper给出了这样的描述:"在关闭时访问foreach变量.使用不同版本的编译器编译时可能会有不同的行为." 为什么它会有不同的行为?
有C#4和C#5之间的重大更改是由于的foreach循环变量被封锁影响的方式,特别是因为在C#中引入lambda表达式3 ReSharper的是警告你的这个,如果你可能依赖或以其他方式已经开始期待前一种语义.
快速结果是在C#4中,循环变量在循环的每次迭代之间共享,并且闭包捕获变量,因此当它们关闭循环变量时,它导致大多数人意外的结果.
在C#5中,循环的每次迭代都有自己的变量,因此一次迭代中的闭包不会在与其他迭代相同的变量上关闭,从而导致更多的预期结果(对于大多数人来说).
这让我们了解你的问题的核心:
在第一个片段中,所有任务都以自己的消息开头,而在第二个片段中,所有任务都以相同的消息开头?
在第一个片段中,您将在循环内创建循环变量的副本,并且闭包发生在内部变量上.在第二个中,您直接关闭循环变量.据推测,您在C#4下运行,因此前一种语义适用.如果在C#5中运行,两个版本的循环输出应该是一致的.这是Resharper所引用的更改,它还应该让您了解如何在C#4中构建代码(即,使用您编写的第一个版本).
正如Justin Pihony在评论中指出的那样,Eric Lippert撰写了一篇关于前语义的非常有用的博客文章,该文章也提到了C#5的变化.
| 归档时间: |
|
| 查看次数: |
6837 次 |
| 最近记录: |