【发布时间】:2019-08-05 13:53:48
【问题描述】:
我对线程安全方法参数的理解是:按值传递给方法的参数作为数据的副本传递,这些数据在方法调用的参数中给出,因此它们是唯一的方法调用,并且不能被任何其他任务更改。相反,引用参数很容易被其他任务中运行的代码更改。
话虽如此,我还不清楚为什么以下代码(没有制作循环计数器的本地副本)在每个线程中返回相同的数字。
static void ExampleFunc(int i) =>
Console.WriteLine("task " + i);
for (int i = 0; i < 10; i++)
{
int taskN = i; //local copy instead of i
Task.Run(() => Func(i));
}
实际输出为:task 10 十次
通过传递 taskN 而不是 i,我得到了正确的输出(任务 1 到 10)。
我希望得到相同的结果,因为我传递的是类型值参数。
【问题讨论】:
-
这被称为变量捕获 - 它发生在 lambda 表达式的上下文中。
-
问题是关于我使用 taskN 与使用 i 得到的输出之间的差异。正如@500-InternalServerError 所说,它可能是变量捕获我正在寻找的主题。我正在阅读它。
-
I get the correct output (task 1 to 10)你的意思是 0 到 9 吗?我问的原因是这应该是你的第一个线索。一个显示 0 到 9,另一个主要显示 10。这通常表明您在 循环有效退出后使用循环变量。
标签: c# multithreading thread-safety parameter-passing