9

asyncキーワードはCILを変更ます(メソッド内に await がない場合でも) が、主に存在できるようにするためのものです。await

しかし、次のことが起こるとは予想していませんでした。

static void Main(string[] args)
{
    Task t = Go();
    t.Wait();
}

static async Task Go()
{
    Console.WriteLine(1);
    await AAA(3000);
    Console.WriteLine(2);
}


static  Task<object> AAA(int a) // <--- No `async`
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    Task.Delay(a).ContinueWith(b => tcs.SetResult(null));
    return tcs.Task;
}

このプリント:

1
(wait)
2

でも私が変われば

static  Task<object> AAA(int a) 

static async  Task<object> AAA(int a) 

それは印刷します:

1
2
(no wait)

質問

遅延が表示されないのはなぜですか? TCS は 3 秒後にのみ解決されます。その間、タスクは解決されず、待機する必要があります。

4

3 に答える 3

8

のタスクをasync返すキーワードがないので、それが完了するのを待ちます (遅延が完了した後に発生します)。TaskCompletionSourceAAA

ただし、asyncキーワードを追加すると、メソッドから返されるタスクは、同期的に完了する状態マシンのタスクになります。そのタスクの内部には (結果として)TaskCompletionSourceのタスクがありますが、それはあなたが待っているタスクではありません。

そのメソッドを のタスクを待機させたい場合はTaskCompletionSource、 の内部タスクを待機できますTask<Task>

await ((Task) await AAA(3000));

または、TaskCompletionSourceを返す代わりに を待ちます:

async Task AAA(int a)
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    Task.Delay(a).ContinueWith(b => tcs.SetResult(null));
    await tcs.Task;
}

またはさらに良いことに、それ自体を待っているだけTask.Delayです:

async Task<object> AAA(int a)
{
    await Task.Delay(a);
    return null;
}
于 2015-09-25T15:38:02.220 に答える
6

Task戻り値の型が async メソッドから返されたときに、タスク (待機していると予想される) を内部でTask<object>取得するためです。Task<Task>あなたがすべきこと:

static async Task<object> AAA(int a)
{
  await Task.Delay(a);
  return null;
}

つまり、async-await とダイレクト タスク操作を 1 つのメソッドに混在させないようにしてください。

于 2015-09-25T15:37:21.387 に答える
2

Serg が述べたように、Visual Studio で次の例を見てください。

        static async Task<int> AAA(int a) // <--- No `async`
        {
             TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
             Task.Delay(a).ContinueWith(b =>
             {
                  tcs.SetResult(1);
             });
             return tcs.Task;
        }

次のようなエラーが表示されます。

これは非同期メソッドであるため、メソッドが同期的に実行されるため、戻り式は 'Task' ではなく 'int' 型である必要があります。intそのため、 ではなくを返す必要がありTaskます。

于 2015-09-25T15:40:58.847 に答える