【C#】【Task】Taskでマルチスレッドするときの、async/awaitのある時、ない時の処理の実行順の実験２

# やりたいこと
Taskの中でawaitをつけたTask、つけてないTaskを走らせて、どういう動作をするか確認したい。

```cs
Thread MainThread;
Thread TaskThread;
Thread TaskThread2;
Thread TaskThread3;
bool endflag = false;

private async void Button_Click_7(object sender, RoutedEventArgs e)
{
    MainThread = Thread.CurrentThread;

    distThreadStatus("■Mainスレッド(Taskスレッド1開始前)");

    endflag = false;
    await Task.Run(() =>
    {
        TaskThread = Thread.CurrentThread;
        distThreadStatus("■Taskスレッド1開始");

        Task.Run(async () =>
        {
            TaskThread2 = Thread.CurrentThread;
            distThreadStatus("■Taskスレッド2開始");

            await Task.Run(() =>
            {
                TaskThread3 = Thread.CurrentThread;
                distThreadStatus("■Taskスレッド3 Sleep前");

                Thread.Sleep(2000);

                distThreadStatus("■Taskスレッド3 Sleep後");
                endflag = true;
            });
            distThreadStatus("■Taskスレッド2抜ける");
        });

        while (!endflag)
        {
            Thread.Sleep(100);
            Console.WriteLine("Looping..");
        }

        distThreadStatus("■Taskスレッド1抜ける");
    });
    distThreadStatus("■Taskスレッド終了後");
}

private void Button_Click_5(object sender, RoutedEventArgs e)
{
    distThreadStatus("■メインスレッド(別ボタン押下)");
}

void distThreadStatus(string title)
{
    Console.WriteLine(title);
    Console.WriteLine($" MainThreadの状態(ID:{MainThread.ManagedThreadId})：{MainThread.ThreadState}");
    if (TaskThread != null) Console.WriteLine($" TaskThreadの状態(ID:{TaskThread.ManagedThreadId})：{TaskThread.ThreadState}");
    if (TaskThread2 != null) Console.WriteLine($" TaskThread2の状態(ID:{TaskThread2.ManagedThreadId})：{TaskThread2.ThreadState}");
    if (TaskThread3 != null) Console.WriteLine($" TaskThread3の状態(ID:{TaskThread3.ManagedThreadId})：{TaskThread3.ThreadState}");
}

```



```
■Mainスレッド(Taskスレッド開始前)
 MainThreadの状態(ID:1)：Running
■Taskスレッド開始
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background
■Taskスレッド2開始
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background, WaitSleepJoin
 TaskThread2の状態(ID:3)：Background
■Taskスレッド3 Sleep前
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background, WaitSleepJoin
 TaskThread2の状態(ID:3)：Background
 TaskThread3の状態(ID:7)：Background
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
Looping..
■Taskスレッド3 Sleep後
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background, WaitSleepJoin
 TaskThread2の状態(ID:3)：Background
 TaskThread3の状態(ID:7)：Background
■Taskスレッド2抜ける
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background, WaitSleepJoin
 TaskThread2の状態(ID:3)：Background
 TaskThread3の状態(ID:7)：Background
Looping..
■Taskスレッド1抜ける
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background
 TaskThread2の状態(ID:3)：Background
 TaskThread3の状態(ID:7)：Background
■Taskスレッド終了後
 MainThreadの状態(ID:1)：Running
 TaskThreadの状態(ID:4)：Background
 TaskThread2の状態(ID:3)：Background
 TaskThread3の状態(ID:7)：Background
```

# 実験結果と理解したことメモ

- asyncを付けてるメソッドは、
    - 自分は非同期処理を行うので、処理完了していなくても下に抜けていきますよ、ということを表明している。
    - また、自分の処理の完了を待ちたかったら、自分に「await」を付けてくださいよ、ということを表明している。
- Taskの中でawaitが出てくると、そのawaitがついているTaskが終わるまで待つ。
- そのTaskと並行して、呼び元のasyncのついていないスレッドは処理を続けている。（ここでいうところの、`■Taskスレッド1`は、`■Taskスレッド2`とその中の`■Taskスレッド3`が開始してawaitに入っても処理が続けて実行されている）
- UIが固まらないのは、ここでいうところのボタン押下時のasyncがついたハンドラ「Button_Click_7」の完了を待たずに、UIの自分の処理をしているから。(UI的には、Button_Click_7の中の処理は、投げっぱなしで完了を待たなくてよい処理ということ)

たぶん、UIが固まらないのは、ボタンのハンドラの中の処理と、UIのその他の処理が、ここでいうところの`■Taskスレッド1`と`■Taskスレッド2`のようになっているからではないか。
(Taskスレッド1(の中のwhile文)がUIの画面処理にあたり、Taskスレッド2が、投げっぱなしにしたハンドラの処理にあたるのでは。)