Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C Task.run(),将参数传递给_C#_Asynchronous_Concurrency_Task - Fatal编程技术网

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

C# C Task.run(),将参数传递给,c#,asynchronous,concurrency,task,C#,Asynchronous,Concurrency,Task,考虑以下代码 attempt = 0; for (int counter = 0; counter < 8; counter++) { if (attempt < totalitems) { Tasklist<output>.Add(Task.Run(() => { return someasynctask(inputList[attempt]); })); }

考虑以下代码

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个并发任务,每个任务同时处理不同的输入,最后在所有任务完成后检查结果。 因为我没有等待任务完成。在开始任务之前,运行尝试会增加,并且当任务启动时,由于尝试值的不确定性,inputlist中可能存在未处理或未处理两次或两次以上的项


如何做到这一点?

问题在于lambda的使用:when Task.Run=>return someasynctaskinputList[trust];在执行过程中到达,则捕获变量尝试,而不是其值,即它是一个闭包。因此,当执行lambda时,将使用该特定时刻的变量值

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

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

问题在于lambda的使用:when Task.Run=>return someasynctaskinputList[trunt];在执行过程中到达,则捕获变量尝试,而不是其值,即它是一个闭包。因此,当执行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提取到一个方法中,该方法位于自动生成的类中,该类引用了尝试变量。这一点很重要:生成的代码只引用另一个类中的变量;它不会复制它。因此,尝试的每一个变化都可以通过该方法看到

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

输入尝试为0的循环 将lambda-like方法的调用添加到任务列表中 增加尝试 重复 在循环之后,您有一些方法调用等待执行,但是每个方法调用都引用同一个变量,因此共享它的值——最后一个受影响的变量


要了解更多详细信息,我真的建议您深入阅读C或类似的书籍-web上有很多关于C闭包的资源:

感谢@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提取到一个方法中,该方法位于自动生成的类中,该类引用了尝试变量。这一点很重要:生成的代码只引用另一个类中的变量;它不会复制它。因此,尝试的每一个变化都可以通过该方法看到

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

输入尝试为0的循环 将lambda-like方法的调用添加到任务列表中 增加尝试 重复 在循环之后,您有一些方法调用等待执行,但是每个方法调用都引用同一个变量,因此共享它的值——最后一个受影响的变量



要了解更多详细信息,我真的建议您深入阅读C或类似的书籍-web上有很多关于C闭包的资源:

您应该提供一个MCVE。。。无论如何,正如我理解你所说的,你的问题是变量尝试在你开始任务时没有预期的值,对吗?PLINQ可能会有帮助。是的,你是对的!尝试值的更改比启动任务@gobesIsn要快得多这不是一个与闭包相关的问题吗?看看这里:你应该提供一个MCVE。。。无论如何,正如我理解你所说的,你的问题是变量尝试在你开始任务时没有预期的值,对吗?PLINQ可能会有帮助。是的,你是对的!尝试值的更改比启动任务@gobesIsn要快得多这不是一个与闭包相关的问题吗?看看这里:你能告诉我怎么做吗?我在lambada内部创建了一个副本,现在它可以工作了,但仍然是一个问题?该解决方案是否始终有效,或者有时可能存在一些不一致性?应在lambda本身中声明“localtrunt”以强制复制该值;在您的代码中仍然存在闭包问题。我不知道什么是闭包问题:csharpindepth.com/Articles/Chapter5/Closures.aspx中有很多内容需要阅读。我想要一个更简单的教程@gobesCould你能告诉我怎么做吗?我在lambada内部创建了一个副本,现在它可以工作了,但还是一个问题?该解决方案是否始终有效,或者有时可能存在一些不一致性?应在lambda本身中声明“localtrunt”以强制复制该值;在您的代码中仍然存在闭包问题。我不知道什么是闭包问题:csharpindepth.com/Articles/Chapter5/Closures.aspx中有很多内容需要阅读。我想要一个更简单的教程@gobesint tmpatempt=trunt;应该在任务之上。运行,对吗?对于在这里绊倒的人,最好滚动到下一个答案。这个答案是错误的。请参见此图。int tmpatempt=trunt;应该在任务之上。R 联合国,对吗?对于在这里绊倒的人,最好滚动到下一个答案。这个答案是错误的。看这个。