3

我不能t在下面的代码中的任务操作委托中使用我的任务 ( ) 的实例。我收到以下错误:

使用未分配的局部变量 't'

代码:

Task t = Task.Factory.StartNew(() =>
{
    MessageBox.Show(t.Id.ToString());
});

现在,如果我执行以下操作,它会起作用:

Task t = null;
t = Task.Factory.StartNew(() =>
{
    MessageBox.Show(t.Id.ToString());
});

有人可以解释为什么会这样吗?

4

2 回答 2

4

C# 编译器对Task.Factory.StartNew. 就编译器而言,访问t可能在调用之后的任何时间发生StartNew,包括t分配之前的时间。

您的第二个代码片段有一个竞争条件:如果并发线程上的任务在分配完成之前显示消息框,您将看到一个空引用异常。

试试这个实验:

private static Task Wrapper(Action f) {
    var res = Task.Factory.StartNew(f);
    Thread.Sleep(1000);
    return res;
}

Task.Factory.StartNew现在用第二个代码段中的调用替换直接调用Wrapper,然后观察程序崩溃。

Task t = null;
t = Wrapper(() => {
    MessageBox.Show(t.Id.ToString());
});
于 2012-07-26T11:09:25.393 回答
2

您必须首先为 t 赋值,以便它获得对 Task 类型对象的引用。

在您的第一段代码中,您尝试为 t 分配一个值并在一个语句中使用它(那里只有一个分号)。

在第二个示例中,这是两个单独的语句,因此它会起作用。

于 2012-07-26T11:08:51.680 回答