c# - 将具有变化值的参数传递给任务 - 行为?

标签 c# .net-4.0 scope task-parallel-library

场景:循环中的异步任务执行一个方法,该方法包含随着程序的继续而改变的参数:

while(this._variable < 100)
{
    this._variable++; 
    var aTask = Task.Factory.StartNew(() =>
    {
        aList.add(this._variable);
        update(this._savePoint);
    });
}

如果循环运行速度快于任务完成速度,列表会添加变量的当前值还是变量保存在本地并添加原始值?

最佳答案

闭包关闭变量,而不是值。因此,递增 _variable 可以改变引用它的任务的行为。

您可以通过制作本地副本来防止这种情况:

while (this._variable < 100)
{
    this._variable++;
    int local = _variable;
    var aTask = Task.Factory.StartNew(() =>
    {
        aList.add(local);
        update(this._savePoint);
    });
} 

或者您可以将值作为状态传递给任务:

while (this._variable < 100)
{
    this._variable++;
    var aTask = Task.Factory.StartNew(object state =>
    {
        aList.add((int)state);
        update(this._savePoint);
    }, this._variable);
} 

它们都通过将 _variable 的值复制到一个新的临时变量来工作。在第一种情况下,local 变量是在循环范围内定义的,因此每次迭代都会得到一个新变量。在第二种情况下,当您将 _variable 的值作为 state 参数传递给任务时,您会复制它的值。如果 _variable 是引用类型,这些解决方案将不起作用;你必须执行克隆。

关于c# - 将具有变化值的参数传递给任务 - 行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10179691/

相关文章:

c# - 线程安全数据集

c# - 单元测试Startup.cs

c# - 将 JavaScript/JSON 数组传递给 MVC 'GET' 方法

c++ - 在 vs2005 中通过 COM 引用 .net 4 库

java - 在类的一个实例上找不到公共(public)符号变量 (Java)

c# - 如何用反斜杠替换正斜杠

c# - 是否有一个内置类可以用来解析包含 MySQL 列数据类型的字符串并返回等效的 .NET Type 对象?

windows-7 - .NET Framework 4.0 和绘制 Aero Glass 问题

c++ - 全局范围与全局命名空间

JavaScript:公共(public)、私有(private)、 protected