2014-10-01 39 views
0

Task.Start()被调用时,如何更新参数currentTime发送到WriteToConsole调用Task.Start()时更新参数值?

在下面的示例中,当我声明task0时,currentTime的值设置为1/1/2000。当执行task0.Start();时,currentTime的值已更改为DateTime.Now。但Console.WriteLine显示'1/1/2000'。

我需要做些什么来更新currentTime,以便使用当前值调用task0.Start()?

static void WriteToConsole(DateTime n) 
{ 
    Console.WriteLine(n.ToString()); 
} 
static void Main(string[] args) 
{ 
    DateTime currentTime = new DateTime(2000, 01, 01); 
    Task task0 = new Task(n => WriteToConsole((DateTime)n), currentTime); 

    for (; ;) 
    { 
     currentTime = DateTime.Now; 
     if (true) 
     { 
      task0.Start(); 
     } 
     if (task0.Status.Equals(TaskStatus.Running)) 
     { 
      // Do Something 
     } 
    } 
} 
+0

需要更多的上下文。你是否想创建task0的多个实例,每个实例都有自己的currentTime?在这种情况下,每次启动时都会创建一个新的Task实例。 – 2014-10-01 21:59:38

回答

1
Task task0 = new Task(() => WriteToConsole(currentTime)); 

应该工作,因为变量被捕获,而不是值。

+0

确实“捕获到变量,而不是值”,但DateTime是不可变的,捕获的变量将始终指向同一个不可变对象。调用'currentTime = [一些新的DateTime]'不会改变原始的不可变对象,而只是重新指定'currentTime'指向什么(但是Task的捕获变量仍然指向旧的不可变对象)。 – xpa1492 2014-10-02 04:03:40

+0

不,它不会,这个工程。 – ths 2014-10-02 06:38:31

+0

我站在更正(和惊讶:)! – xpa1492 2014-10-02 06:47:12

0

封装参数的包装类,像这样:

private class DtWrapper 
{ 
    public DateTime CurrentTime {get; set; } 
} 

DtWrapper currentTime = new DtWrapper { CurrentTime = new DateTime(2000, 01, 01) } ; 
Task task0 = new Task(n => WriteToConsole(((DtWrapper)n).CurrentTime), currentTime); 

for (; ;) 
{ 
    currentTime.CurrentTime = DateTime.Now; 
    if (true) 
    { 
     task0.Start(); 
    } 
    if (task0.Status.Equals(TaskStatus.Running)) 
    { 
     // Do Something 
    } 
} 

,如果你有传递当前时间作为自变量(N => ...)没有特别的原因,然后使用这个答案,这是更好的因子。