質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

Q&A

解決済

2回答

970閲覧

【C#】非同期の処理順について

nyarutsun

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

同期

複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

0グッド

0クリップ

投稿2019/02/25 05:41

編集2019/02/25 05:44

前提・実現したいこと

APIの同期・非同期について無知なため教示いただきたいです。
環境
Visual Studio 2018
C#

現状の問題点

ボタンを押した際にAPIにGETリクエストを送り、返ってきた結果をラベルに表示されるというものですが、ブレイクポイントで処理順を確認してみると
表示⇒GETリクエスト
という順で処理がされています。

async/await の記事をみて実装してみたのですが、awaitで待っているような気配が無く質問させていただきました。

自分の中では
GETリクエストメソッドが実行される⇒awaitで結果が保管されるまで待つ⇒メインメソッドに戻り表示
という認識だったのですが、awaitの使い方が間違っているのでしょうか?

ソースコード

static public string token; private void button1_Click(object sender, EventArgs e) { string url = "https://hogehoge.com"; var data = Task.Run(() => { return HttpGet(url, token); }); label1.Text = data.Result;

}
//GETリクエスト処理
async public Task<string> HttpGet(string url, string token)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);

var response = await client.GetAsync(url); return await response.Content.ReadAsStringAsync(); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

もしかして、ブレークポイントのステップ順序というのは、「data.Resultの行に行った次にTask.Runの中に行く」という順序ではありませんか?
dataはawaitしていない単なるTask.Runなので、そこで非同期的に実行するだけして自分はそのまま先に進むことになります。
しかし、その直後にdata.Resultの呼び出しを行っており、そこでdataの結果が得られるまでブロックしているため、結果自体はlabel1に正しく反映されるように見えます。実際には、全く非同期になっていません。
正しくは、button1_Click自体を非同期メソッドにして、その中でlabel1.Textへの書き換えを「HttpGetの続き」として記述します。

非同期の部分だけ書き直してみました。テストはしていませんが。

csharp

1static public string token; 2private async void button1_Click(object sender, EventArgs e) 3{ 4 string url = "https://hogehoge.com"; 5 var data = await HttpGet(url, token); 6 label1.Text = data; 7} 8//GETリクエスト処理 9public async Task<string> HttpGet(string url, string token) 10{ 11 var client = new HttpClient(); 12 client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token); 13 var response = await client.GetAsync(url).ConfigureAwait(false); 14 return await response.Content.ReadAsStringAsync().ConfigureAwait(false); 15}

投稿2019/02/25 07:22

編集2019/02/25 07:25
tamoto

総合スコア4103

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyarutsun

2019/02/26 02:40

回答いただきありがとうございます。 説明もわかりやすく解決いたしました!
guest

0

var data = Task.Run(...)
のナカミは別スレッドで実行されるため、即戻ってきて次の行の実行がなされます

するなら、HttpGetは非同期でないほうがいいかと

var data=HttpGet(url, token);
label1.Text = data.Result;

投稿2019/02/25 05:54

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問