非同期メソッドを持っています。
public async Task<bool> ValidateRequestAsync(string userName, string password)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
string stringResponse = await response.Content.ReadAsStringAsync();
return bool.Parse(stringResponse);
}
}
このメソッドを次のように呼び出します。
bool isValid = await ValidateRequestAsync("user1", "pass1");
同じメソッドを、await
キーワードを使わずに、synchronousメソッドから呼び出すことはできますか?
例
public bool ValidateRequest(string userName, string password)
{
return ValidateRequestAsync(userName, password).Result;
}
これではデッドロックが起きてしまうと思います。
EDIT
上記のようにメソッドを呼び出すと、呼び出しが終わらない。(メソッドはもう最後に到達しません)
UIスレッドなどのシングルスレッド実行コンテキストから非同期メソッドを呼び出し、その結果を同期的に待つと、高い確率でデッドロックが発生します。あなたの例では、その確率は100%です
考えてみてください。を呼び出したらどうなるでしょうか?
ValidateRequestAsync(userName, password).Result
ValidateRequestAsyncというメソッドを呼び出します。その中でReadAsStringAsyncを呼び出す。その結果、タスクがUIスレッドに返され、UIスレッドが利用可能になったときにそのスレッドで実行を継続するようにスケジュールされた継続が行われることになります。しかし、もちろん、タスクが終了するのを待っている(ブロックされている)ので、利用可能になることはありません。しかし、タスクはUIスレッドが使用可能になるのを待っているため、終了することができません'。デッドロック。
このデッドロックを防ぐ方法はありますが、どれもBad Ideaです。念のため、以下のようにするとうまくいくかもしれません。
Task.Run(async () => await ValidateRequestAsync(userName, password)).Result;
これは悪い考えです。なぜなら、あなたはまだUIスレッドをブロックし、待機して何も有用なことをしないからです。
では、解決策は何でしょうか?非同期化することです。UIスレッドの元の呼び出し元はおそらく何らかのイベントハンドラなので、それが非同期であることを確認します。