🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

解決済

2回答

2111閲覧

c# サーバーからのレスポンスを入手してから次の処理に進みたい。

GattoNero

総合スコア26

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2021/01/19 12:52

前提・実現したいこと

Microsoft Azure Face APIに要求を出して、戻ってきたJSONから必要な情報を取得し、次の処理をしたいのですが、
「待つ」という処理について御教授お願いします。

発生している問題・エラーメッセージ

Face APIには、2度に分けて要求する必要があるのですが、最初の要求に対するレスポンスが返ってくる前に
「待つ」処理の仕方が判らず、要求に必要な情報不足のまま2回目のAPIを呼んでいる為、エラーになります。

{ "error": { "code": "BadArgument", "message": "Request body is invalid." } }

該当のソースコード

c#

1namespace FaceFormAPP 2{ 3 public partial class Form1 : Form 4 { 5 string imagefilepath; 6 string FaceId; 7 string MatchedName; 8 9 private void button2_Click(object sender, EventArgs e) 10 { 11 //送信したいイメージファイルのパスとファイル名imagefileppathを得ます。 12 openfile(); 13 //ファイルをFace APIに送信し、FaceIdを取得します。 14 AnalysisRequest(imagefilepath); 15 16 //得たFaceIdを基に該当する氏名を得ます。 17 //**非同期でAnalysisRequestを呼んでいるので 18 //下のルーチンを呼ぶときに必要なFaceIdがまだ確定していない時がある。 19       //なので、1回目のレスポンスが返って来てから下のルーチンを呼びたい。 20 FaceIdentify(); 21 } 22 23 private async void AnalysisRequest(string imageFilePath) 24 { 25 // Face APIの呼び出し 26 response = await client.PostAsync(uri, FaceId); 27 // 実行結果からJSONの取得 28 string jsonString = await response.Content.ReadAsStringAsync(); 29 FaceDetectRead = JsonSerializer.Deserialize<List<FaceDetect>>(jsonString)[0]; 30 FaceId = FaceDetectRead.faceId; 31 } 32 33 private async void FaceIdentify() 34 { 35 content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 36 37 response = await client.PostAsync(uri, content); //contentにFaceIdが必要 38 // 実行結果からJSONの取得 39 string jsonString = await response.Content.ReadAsStringAsync(); 40 // 41 //jsonStringから該当する氏名を得るルーチン 42 MatchedName = "取得した氏名"; 43 // 44 } 45 } 46}

試したこと

Task.Delay()を入れてみましたが、1回目のレスポンスが1秒以上かかるときもあり、上手くいかなかったです。
1回目のレスポンスが返って来てから、2回目の要求を出すにはどうすれば良いでしょうか?

private async void FaceIdentify() { await Task.Delay(1000);

補足情報(FW/ツールのバージョンなど)

Windows 10
Visual studio 2019
C#
Windows Form アプリケーション

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

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

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

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

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

guest

回答2

0

内容あんまり読んでないけど、async/awaitの使い方が根本的に間違ってます。
async voidとしても良いのは基本的にイベントハンドラだけです。

その他の2つのメソッドはasync Taskとする必要があります。
その上で、awaitキーワードを使ってその非同期勝利を呼び出します。

diff

1namespace FaceFormAPP 2{ 3 public partial class Form1 : Form 4 { 5 string imagefilepath; 6 string FaceId; 7 string MatchedName; 8 9- private void button2_Click(object sender, EventArgs e) 10+ private async void button2_Click(object sender, EventArgs e) 11 { 12 //送信したいイメージファイルのパスとファイル名imagefileppathを得ます。 13 openfile(); 14 //ファイルをFace APIに送信し、FaceIdを取得します。 15- AnalysisRequest(imagefilepath); 16+ await AnalysisRequest(imagefilepath); 17 18 //得たFaceIdを基に該当する氏名を得ます。 19 //**非同期でAnalysisRequestを呼んでいるので 20 //下のルーチンを呼ぶときに必要なFaceIdがまだ確定していない時がある。 21       //なので、1回目のレスポンスが返って来てから下のルーチンを呼びたい。 22- FaceIdentify(); 23+ await FaceIdentify(); 24 } 25 26- private async void AnalysisRequest(string imageFilePath) 27+ private async System.Threading.Tasks.Task AnalysisRequest(string imageFilePath) 28 29 // Face APIの呼び出し 30 response = await client.PostAsync(uri, FaceId); 31 // 実行結果からJSONの取得 32 string jsonString = await response.Content.ReadAsStringAsync(); 33 FaceDetectRead = JsonSerializer.Deserialize<List<FaceDetect>>(jsonString)[0]; 34 FaceId = FaceDetectRead.faceId; 35 } 36 37- private void FaceIdentify() 38+ private async System.Threading.Tasks.Task FaceIdentify() 39 { 40 content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 41 42 response = await client.PostAsync(uri, content); //contentにFaceIdが必要 43 // 実行結果からJSONの取得 44 string jsonString = await response.Content.ReadAsStringAsync(); 45 // 46 //jsonStringから該当する氏名を得るルーチン 47 MatchedName = "取得した氏名"; 48 // 49 } 50 } 51}

他にもツッコミどころはありそうですが、とりあえず明らかに間違ってるところは以上。

投稿2021/01/19 13:41

編集2021/01/19 13:51
gentaro

総合スコア8947

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

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

YAmaGNZ

2021/01/19 13:50

private void System.Threading.Tasks.Task button2_Click(object sender, EventArgs e) の部分ミスってます
gentaro

2021/01/19 13:51

ご指摘ありがとうございます。
GattoNero

2021/01/19 21:21

早速のアドバイスありがとうございます。c#は今年始めたばかりで、Face APIの使い方もAzure Faceの コーディング例をコピペしているので、ご指摘のような基本的部分で引っ掛かります。 仕事から帰ってきたら、試してみます。少しお待ちください。
GattoNero

2021/01/23 07:45

返事が遅くなり申し訳ありません。 色々勉強して、何とか解決しました。 自己解決のところにコード載せておきます。
guest

0

自己解決

C#

1namespace Formtest1 2{ 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 private async void button1_Click(object sender, EventArgs e) 11 { 12 textBox1.Text = "重い処理を呼びます"; 13 int Restime = await Ask01(3000); 14 textBox1.Text = "処理時間 " + Restime + "ms"; 15 } 16 17 private async Task<int> Ask01(int waittime) 18 { 19 textBox1.Text = "重い処理中"; 20 await Task.Delay(waittime); 21 int answer = waittime; 22 return answer; 23 } 24 25 private void button2_Click(object sender, EventArgs e) 26 { 27 textBox1.Text = "別スレッドを開始します。"; 28 } 29 } 30}

投稿2021/01/23 07:45

GattoNero

総合スコア26

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問