我理解闭包在引用上而不是封闭变量的值。那不是我的问题。我想知道如何表达(对编译器)“给这个任务这个值,就像创建时一样,而不是在执行时”。
换句话说,我怎样才能获得
static void Main(string[] args)
{
var userName = "Alice";
var task = new Task(() =>
{
Console.WriteLine("User is: " + userName);
});
// continues work ...
userName = "Zoltan";
task.Start();
Console.ReadLine();
}
打印
User is: Alice
而不是它现在所做的,即
User is: Zoltan
我正在努力避免
Task.Factory.StartNew((copy) =>
{
Console.WriteLine("User is: " + (string)copy);
}, userName);
迫使我将每个状态对象(例如userName)重新转换为实际lambda中相应的类型,因为StartNew
方法接口定义类型object
而不是通用接口(例如: <T>
)。上面的演示示例似乎没有字符串和一个写入线 - 但对于具有大型对象的真实情况并且在屏幕代码中重新编写它有点浪费(并且容易出错)。
答案 0 :(得分:3)
我通常只是为这样的闭包场景使用临时变量:
var userName = "Alice";
var taskUserName = userName;
var task = new Task(() =>
{
Console.WriteLine("User is: " + taskUserName);
});
<强>编辑:强>
完成同样事情的另一种方法是将任务创建重构为方法:
static void Main(string[] args)
{
var userName = "Alice";
var task = CreateUserTask(userName);
// ...
}
static Task CreateUserTask(string taskUserName)
{
return new Task(() =>
{
Console.WriteLine("User is: " + taskUserName);
});
}