我有一个将long by值传递给Task的问题。
我有一个ID列表,我遍历每个ID,分配给一个局部变量,然后作为参数传递给一个新的Task。在循环并处理下一个ID之前,我不等待任务完成。我保留了一系列任务,但这无关紧要。
loop
long ID = list[index];
task[index] = Task.Factory.StartNew(() => doWork(ID));
end loop
如果列表包含例如100和200.我希望第一个任务调用100 然后用200调用第二个任务。但事实并非如此,doWork接收两个任务200,因此复制值时会出现问题。
我可以用一些简单的控制台代码来演示
class Program
{
static void Main(string[] args)
{
long num = 100;
Task one = Task.Factory.StartNew(() => doWork(num));
num = 200;
Console.ReadKey();
}
public static void doWork(long val)
{
Console.WriteLine("Method called with {0}", val);
}
}
以上代码将始终显示
使用200
调用的方法我修改了代码以等待任务状态从WaitingToRun切换
static void Main(string[] args)
{
long num = 100;
Task one = Task.Factory.StartNew(() => doWork(num));
while(one.Status == TaskStatus.WaitingToRun)
{}
num = 200;
Console.ReadKey();
}
这改善了事情,但不是100%证明,经过几次运行,我得到了200调用方法
还尝试了以下
while (true)
{
if (one.Status == TaskStatus.Running | one.IsCompleted == true)
break;
}
但又显示了200个。
任何想法如何保证传递给任务的价值而不等待任务完成?
任何帮助/建议表示赞赏 ADE
答案 0 :(得分:8)
任何想法如何保证传递给任务的价值而不等待任务完成?
当然 - 只需创建一个单独的变量,不会在其他地方进行修改。您可以使用新范围来明确说明:
long num = 100;
Task one;
{
// Nothing can change copyOfNum!
long copyOfNum = num;
one = Task.Factory.StartNew(() => doWork(copyOfNum));
}
您无法更改C#编译器以捕获“创建委托时变量的值”而不是捕获变量,但您可以确保变量之后不会更改,从而完成相同的操作。 / p>