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

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

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

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

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Q&A

1回答

606閲覧

awaitの後の挙動

ya_ay

総合スコア13

C#

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

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

0グッド

0クリップ

投稿2022/09/11 13:08

問題

C#初心者です。
ボタン押した後、Main→TaskSampleが呼ばれ、
awaitを実行したあと、SubTask1が動きますが、すぐに戻ってきて"test"が出力されてしまいます。
こういう仕様なのでしょうか。そもそも書きかたがおかしいでしょうか。

実現したいこと

SubTask1が終わり、"Taskおわり"が出力後、"test”が出力されるような動きにしたいです。

該当のソースコード

C#

1 private void Main() 2 { 3 TaskSample(); 4 Console.WriteLine("test"); 5 6 } 7 8 private async void TaskSample() 9 { 10 await Task.Run(()=>SubTask1()); 11 Console.WriteLine("Taskおわり"); 12 } 13 14 private void SubTask1() 15 { 16 Thread.Sleep(10000); 17 18 } 19 20 private void button1_Click(object sender, EventArgs e) 21 { 22 Main(); 23 } 24 25

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/09/13 01:19

質問者さん、無言ですが、回答したのでそれに対するフィードバックを返してください。役に立った/立たなかったぐらいはすぐに返せるのでは? 役に立たなかったならどこがダメかを書くとより期待に近い回答が出てくるかも。とにかく無言は NG です。
退会済みユーザー

退会済みユーザー

2022/09/13 23:29

スレッドを放置しておかないでクローズしてください。問題は解決したはず。 解決したら、解決に役に立った回答にベストアンサーをつけてスレッドをクローズするのがここでのマナーです。
guest

回答1

0

難しいかもしれませんが、読んでみましょう。

非同期プログラミングのベスト プラクティス
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

「async void を避ける」と「すべて非同期にする」・・・できてないですよね。特に後者が問題。


【追記】

具体的にどう直せばいいかを追記しておきます。

(1) すべて非同期にする

"上から下に (または下から上に) 非同期コードが他の非同期コードを呼び出す"

⇒ button1_Click, Main も async/await を付与して非同期メソッドにします。

(2) async void を避ける

"async メソッドで自然な戻り値の型は Task と Task<T> だけです"

⇒ 戻り値がない場合は async Task とします。ただしイベントハンドラは例外で、async void とするほかありませんので注意。

質問者さんのコードを上の (1), (2) に従って書き換えると以下のようになります(注: button1 ⇒ button3、Main ⇒ Test、Console ⇒ System.Diagnostics.Debug と変更しています)

private async void button3_Click(object sender, EventArgs e) { await Test(); } private async Task Test() { await TaskSample(); System.Diagnostics.Debug.WriteLine("test"); } private async Task TaskSample() { await Task.Run(() => SubTask1()); System.Diagnostics.Debug.WriteLine("Taskおわり"); } private void SubTask1() { Thread.Sleep(10000); }

結果は:

イメージ説明

投稿2022/09/11 14:21

編集2022/09/12 00:24
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ya_ay

2022/09/13 13:42

詳細に記載ありがとうございました。 今後の参考にさせていただきます。 Microsoftの記事を読みましたが難解でした。 非同期の処理というものは思いのほか難しいということがわかり今後勉強していきます。
退会済みユーザー

退会済みユーザー

2022/09/13 14:14

スレッドをクローズしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問