2

次の単純なコンソール アプリケーションがあります。

class Program
{
    private static int times = 0;

    static void Main(string[] args)
    {
        Console.WriteLine("Start {0}", Thread.CurrentThread.ManagedThreadId);

        var task = DoSomething();
        task.Wait();

        Console.WriteLine("End {0}", Thread.CurrentThread.ManagedThreadId);

        Console.ReadLine();
    }

    static async Task<bool> DoSomething()
    {
        times++;

        if (times >= 3)
        {
            return true;
        }

        Console.WriteLine("DoSomething-1 sleeping {0}", Thread.CurrentThread.ManagedThreadId);
        await Task.Run(() =>
        {
            Console.WriteLine("DoSomething-1 sleep {0}", Thread.CurrentThread.ManagedThreadId);
            Task.Yield();
        });
        Console.WriteLine("DoSomething-1 awake {0}", Thread.CurrentThread.ManagedThreadId);

        Console.WriteLine("DoSomething-2 sleeping {0}", Thread.CurrentThread.ManagedThreadId);
        await Task.Run(() =>
        {
            Console.WriteLine("DoSomething-2 sleep {0}", Thread.CurrentThread.ManagedThreadId);
            Task.Yield();
        });
        Console.WriteLine("DoSomething-2 awake {0}", Thread.CurrentThread.ManagedThreadId);

        bool b = await DoSomething();
        return b;
    }
}

出力で

Start 1
DoSomething-1 sleeping 1
DoSomething-1 sleep 3
DoSomething-1 awake 4
DoSomething-2 sleeping 4
DoSomething-2 sleep 4
DoSomething-2 awake 4
DoSomething-1 sleeping 4
DoSomething-1 sleep 3
DoSomething-1 awake 3
DoSomething-2 sleeping 3
DoSomething-2 sleep 3
DoSomething-2 awake 3
End 1

コンソール アプリは SynchronizationContext を提供しないため、タスクはスレッド プールで実行されます。しかし、私が驚いたのは、await から実行を再開するとき、await 内DoSomethingと同じスレッドにいるということです。私は、待機中のメソッドの実行を再開するときに、待機していたスレッドに戻るか、完全に別のスレッドにいると想定していました。

誰かが理由を知っていますか?私の例は何らかの形で欠陥がありますか?

4

2 に答える 2