36239


タイトルの通りなのですが、条件があります。

  * ConsoleアプリのProgram.csで実行すると問題なく、レスポンスを得る事ができる。
  * WPFプロジェクトのソースコード上ではレスポンスが帰って来ない。(MainWindow.xaml.cs)

レスポンスが帰ってこないコードは以下の内容です。 AzureMLのAPIの結果を取得する内容です。

[code]

    public class Study
    {
        public Study()
        {
            InvokeRequestResponseService().Wait();
        }
    
        public class StringTable
        {
            public string[] ColumnNames { get; set; }
            public string[,] Values { get; set; }
        }
    
        static async Task InvokeRequestResponseService()
        {
            using (var client = new HttpClient())
            {
                var scoreRequest = new
                {
    
                    Inputs = new Dictionary<string, StringTable>() {
                        {
                            "input1",
                            new StringTable()
                            {
                                ColumnNames = new string[] {"メーカー", "燃料タイプ", "ドアの数", "車体形状", "エンジンの場所", "エンジンサイズ", "値段"},
                                Values = new string[,] {  { "audi", "gas", "two", "sedan", "front", "136", "0" }  }
                            }
                        },
                    },
                    GlobalParameters = new Dictionary<string, string>()
                    {
                    }
                };
                const string apiKey = "***myKey***"; // Replace this with the API key for the web service
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    
                client.BaseAddress = new Uri("***myUri***");
    
    
                //↓ここのレスポンスがなく、これ以上進まない…
                HttpResponseMessage response = await client.PostAsJsonAsync("", scoreRequest);
    
                if (response.IsSuccessStatusCode)
                {
                    string result = await response.Content.ReadAsStringAsync();
                    Console.WriteLine("Result: {0}", result);
                }
                else
                {
                    Console.WriteLine(string.Format("The request failed with status code: {0}", response.StatusCode));
    
                    // Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure
                    Console.WriteLine(response.Headers.ToString());
    
                    string responseContent = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseContent);
                }
            }
        }
    }
    
[/code]

ブレイクポイントで張って待っていても何もレスポンスがないため、アプリはフリーズ状態です。  
何か原因がわかる方、ご教授いただきたいです。  
よろしくおねがいします。


CC BY-SA 3.0
2017-07-10T02:39:14.930
36237
2017-07-10T03:22:20.053
2017-07-10T03:22:20.053
5750
12388
question
c# wpf azure
HttpResponseMessageの応答が全くない…


以下の2種類の処理がデッドロックしています。

  1. `InvokeRequestResponseService().Wait()`
  2. `InvokeRequestResponseService()`内の`await`

WPFアプリで実行される`await`は標準では後続の処理をUIスレッドで実行しようとします。しかしUIスレッドでは`Task.Wait()`をずっと実行しているため、`await`が完了しないのです。

対策としてはまず`Task`を`await`する前に`.ConfigureAwait(false)`を実行し後続の処理のスレッドを変更する方法があります。例えば以下のようなコーディングになります。

[code]

     await client.PostAsJsonAsync("", scoreRequest).ConfigureAwait(false)
    
[/code]

より重要な点としてはUIスレッドで`Task.Wait()`を実行すべきではないということです。折角非同期処理を行っているのにUIをブロックしてはあまり意味がありません。ですので`InvokeRequestResponseService().Wait()`を例えば以下のように変更すると画面がフリーズすることはなくなります。

[code]

    IsEnabled = false; // 画面をロード中表示に変更する
    // awaitで待機
    await InvokeRequestResponseService();
    IsEnabled = true;
    
[/code]

どちらか一方でも効果はありますが、両方行った方が良いです。


CC BY-SA 3.0
2017-07-10T03:00:29.770
36239
2017-07-10T03:18:57.060
2017-07-10T03:18:57.060
5750
5750
36237
answer