ボタンクリックで非同期メソッドを呼び出す
質問
Windows Phone 8.1 プロジェクトを作成しました。
async
メソッド
GetResponse<T>(string url)
を実行し、メソッドが終了するのを待ちますが、メソッドが終了することはありません。以下は私のコードです。
private void Button_Click(object sender, RoutedEventArgs
{
Task<List<MyObject>> task = GetResponse<MyObject>("my url");
task.Wait();
var items = task.Result; //break point here
}
public static async Task<List<T>> GetResponse<T>(string url)
{
List<T> items = null;
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
try
{
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = strReader.ReadToEnd();
items = JsonConvert.DeserializeObject<List<T>>(text);
}
catch (WebException)
{
throw;
}
return items;
}
にぶら下がります。
task.Wait()
.
ボタンのクリックメソッドを
async
に変更し
await
の前に
async
メソッドを呼び出すと、その結果 (
await GetResponse<string>("url")
). 何が問題なのかというと
Task<List<string>> task = GetResponse<string>("url")
?
私は何を間違えているのでしょうか?
助けてくれてありがとうございます。
どのように解決するのですか?
あなたは古典的なデッドロックの犠牲者です。
task.Wait()
または
task.Result
はUIスレッドのブロック呼び出しで、デッドロックの原因となります。
UIスレッドでブロックしない
. 絶対にしないでください。ただ
await
にしてください。
private async void Button_Click(object sender, RoutedEventArgs
{
var task = GetResponseAsync<MyObject>("my url");
var items = await task;
}
ところで、なぜ
WebException
をキャッチして投げ返しているのでしょうか?単にキャッチしない方が良いのでは?どちらも同じです。
の中で、非同期コードと同期コードを混ぜているのもわかります。
GetResponse
メソッド内で非同期コードと同期コードを混在させていることがわかります。
StreamReader.ReadToEnd
はブロッキングコールです。
StreamReader.ReadToEndAsync
.
また、TAP("Task based Asynchronous Pattern")に従い、タスクや非同期を返すメソッドには"Async" を付けてください。 Jonのコメント .
上記の懸念事項をすべて解決したら、あなたのメソッドは次のようになるはずです。
public static async Task<List<T>> GetResponseAsync<T>(string url)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = (HttpWebResponse)await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
Stream stream = response.GetResponseStream();
StreamReader strReader = new StreamReader(stream);
string text = await strReader.ReadToEndAsync();
return JsonConvert.DeserializeObject<List<T>>(text);
}
関連
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み] C#でベースコンストラクタを呼び出す
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] C#で同期メソッドから非同期メソッドを呼び出すには?
-
[解決済み] 非同期Task<T>メソッドを同期的に実行するにはどうしたらいいですか?
-
[解決済み] async/await - タスクとvoidをいつ返すか?
-
[解決済み】コンソールアプリのMainメソッドにasync修飾子を指定できない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み] [Solved] .NETでスレッドの終了を待つには?
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】スレッド終了またはアプリケーションの要求により、I/O操作が中断されました。