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呼び出し後いつでも発生する可能性があります。StartNewt

2 番目のコード スニペットには競合状態があります。割り当てが完了する前に同時スレッドのタスクがメッセージ ボックスを表示するようになると、null 参照例外が表示されます。

この実験を試してください:

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

次に、2 番目のスニペットでの直接呼び出しをの呼び出しに置き換えてTask.Factory.StartNew、プログラムがクラッシュするのを確認します。Wrapper

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

タイプ Task のオブジェクトへの参照を取得するために、最初に t に値を割り当てる必要があります。

コードの最初のビットでは、値を t に割り当て、それを 1 つのステートメントで使用しようとします (セミコロンは 1 つだけです)。

2 番目の例では、これらは 2 つの別個のステートメントであるため、機能します。

于 2012-07-26T11:08:51.680 に答える