繁体   English   中英

C#Task.run(),将参数传递给

[英]C# Task.run(), passing parameter to

请考虑以下代码

attempt = 0;
for (int counter = 0; counter < 8; counter++)
{
    if (attempt < totalitems)
    {
        Tasklist<output>.Add(Task.Run(() =>
        {
            return someasynctask(inputList[attempt]);
        }));
    }
    else
    {
        break;
    }
    attempt++;
}
await Task.WhenAll(Tasklist).ConfigureAwait(false);

我希望有8个并发任务,每个任务同时处理不同的输入,最后检查结果,当它们全部完成时。 因为我没有等待Task.Run()的完成尝试在任务开始之前增加,并且当任务开始时,输入列表中可能存在未处理或处理两次或更多次的项目(由于不确定性)在尝试价值。

怎么做?

问题在于使用“lambda”:当Task.Run(() => return someasynctask(inputList[attempt])); 在执行期间到达,变量attempt被捕获,而不是它的值(即它是“闭包”)。 因此,当执行lambda时,将使用该特定时刻的变量值。

只需在lambda之前添加变量的临时副本,然后使用它。 例如

if (attempt < totalitems)
{
    int localAttempt = attempt;
    Tasklist<output>.Add(Task.Run(() =>
    {
        return someasynctask(inputList[localAttempt]);
    }));
}

感谢@gobes的回答:

尝试这个:

attempt = 0;
for (int counter = 0; counter < 8; counter++)
{
    if (attempt < totalitems)
    {
        Tasklist<output>.Add(Task.Run(() =>
        {
            int tmpAttempt = attempt;
            return someasynctask(inputList[tmpAttempt]);
        }));
    }
    else
    {
        break;
    }
    attempt++;
}
await Task.WhenAll(Tasklist).ConfigureAwait(false);

实际上,编译器正在做的是将lambda提取到一个方法中,该方法位于一个自动生成的类中,该类引用了try变量。 这一点非常重要:生成的代码只引用另一个类的变量; 它没有复制它。 因此,方法可以看到每次尝试的变化。

执行过程中发生的事情大致如下:

用try = 0进入循环向你的任务列表添加一个类似lambda的方法的调用增加尝试重复循环之后,你有一些方法调用等待(没有双关语意图)执行,但是每个方法调用引用相同的变量因此,分享它的价值 - 最后影响它。

有关更多详细信息,我真的建议深入阅读C#,或者同类书籍 - 关于C#在Web上关闭的资源很多:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM