78362


## 実現したいこと

非同期で気象庁の気象データを`Console.WriteLine()`で表示させたいです。

## 困っていること

`async`, `await`が止まってしまい、次のタスクへすすまず`Console.WriteLine()`で表示されなくなってしまいました。

[code]

    using Newtonsoft.Json.Linq;
    using System;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace Weather
    {
        public partial class Weather : Form
        {
            public Weather()
            {
                InitializeComponent();
    
                var url = "https://www.jma.go.jp/bosai/forecast/data/forecast/010000.json";
    
                var task = WeatherAPI.FetchWeatherJsonData(url);
    
                task.Wait();
    
                var json = task.Result;
    
                foreach (var e in json)
                {
                    Console.WriteLine(e);
                }
            }
    
            class WeatherAPI
            {
                public static async Task<JObject> FetchWeatherJsonData(string url)
                {
                    var uri = new Uri(url);
                    var httpClient = new HttpClient();
                    var data = await httpClient.GetStringAsync(uri);
                    var json = JObject.Parse(data);
                    return json;
                }
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2021-07-21T01:00:45.433
78332
2021-07-22T11:13:52.107
40856
question
c# http
C#で天気情報(JSON)をasyncでとってきて、表示させたいのですが、処理が止まってしまいます。


典型的なデッドロックパターンです。

microsoftによるベストプラクティスはこちらになります。  
<https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2013/march/async-
await-best-practices-in-asynchronous-programming>

これだけ読んでもよくわからないと思うので、補足説明を書きます。

  1. await FooAsync()したとき、FooAsyncの中身は別スレッドで動作し、それが終了する時に元のコンテキスト（スレッドのグループのようなもの）に戻そうとします。
  2. Windows Formアプリケーションにおいて、UIコンテキストには単一のスレッドしか存在しません。
  3. task.Wait()を命令したのがUIコンテキストだった場合、このコンテキストはスレッドを1つしか持たずそれがWaitするため、事実上taskが完了するまで処理を受け付けなくなります。
  4. taskの中でawait FooAsync()などされている場合、このFooAsync()が終わるときに元のコンテキストに戻そうとします。しかしそれがUIコンテキストだった場合、taskが完了するまで処理を受け付けないのでUIコンテキストに処理を返すことが出来ず、デッドロックします。


CC BY-SA 4.0
2021-07-22T11:07:22.433
78362
2021-07-22T11:13:52.107
2021-07-22T11:13:52.107
25396
25396
78332
answer