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

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

詳細はこちら
C#

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

非同期処理

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

Q&A

解決済

2回答

713閲覧

awaitが分かりません

nankoko

総合スコア20

C#

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

非同期処理

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

0グッド

2クリップ

投稿2021/02/16 05:12

編集2021/02/17 04:29

t1も、t2も同じタスクですが、t2は処理が止まったままConsole.WriteLine("goal");まで到達できません。
t1と、t2では何が違うのでしょうか?

using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { Async(); Console.Read(); } static async Task Async() { Task t1 = Task.Delay( 999); Task t2 = new Task(() => Thread.Sleep( 999)); await t1; //OK await t2; //NG Console.WriteLine("goal"); } }

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

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

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

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

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

m.ts10806

2021/02/16 05:18

何を実現したいがためのコードなのでしょうか。要件具体的に記載してください
nankoko

2021/02/16 05:21

Console.WriteLine("main")を実行したいです。
退会済みユーザー

退会済みユーザー

2021/02/16 05:26 編集

Task t2 = Task.Run(() => Thread.Sleep(1000)); としたらどうなりますか?
nankoko

2021/02/16 05:30

それだともちろん問題ないですが、 どうしてt2は駄目で、t1は問題なく処理されるのかの違いが知りたいです。
m.ts10806

2021/02/16 05:36

質問は編集できますので。 あと、「OK」「NG」「駄目」「できない」ではなく、起きている現象を記載してください。
nankoko

2021/02/17 04:30

今更ですが、後から見られる方のために質問をわかりやすく修正しておきました!
guest

回答2

0

ベストアンサー

「質問ケースでのTaskが動作するorしないことの原理が知りたい」ということだと思うので、以下のページが参考になると思います。

[雑記] スレッド プールとタスク
https://ufcpp.net/study/csharp/misc_task.html

async/awaitと同時実行制御
https://ufcpp.wordpress.com/2012/11/12/asyncawait%E3%81%A8%E5%90%8C%E6%99%82%E5%AE%9F%E8%A1%8C%E5%88%B6%E5%BE%A1/

非同期メソッド入門 (7) - 内部実装を覗く
https://blog.xin9le.net/entry/2012/08/06/123916

端的にいうとStartしてないTaskはawait出来ません。(tをawaitした時点でTaskが完了状態に変わるまで待機し始め、完了状態に変わることはないのでハングアップするはず)

実験コード
https://dotnetfiddle.net/my3T0b

「awaitされたTaskは実行状態になる」というのは誤解で、Taskは誰かしらがStartさせなければ実行状態にはならず、質問のTask tのケースにおいても「awaitしても実行されていないため完了状態にもならず、await元に処理が戻らない」という動作になったと説明できます。(前掲の「非同期メソッド入門 (7) - 内部実装を覗く」のリンクからTaskを返すメソッドの生成コードが見れます)

async Task XXXAsync()といったメソッドを書くと内部的に実行状態にまでセットアップされたTaskを返す処理が生成されており、知らず知らずの内にTaskを実行してくれていたのだとわかります。

投稿2021/02/16 07:47

tor4kichi

総合スコア769

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

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

nankoko

2021/02/17 04:35 編集

お返事遅くなってすみません。 dnSpyでデコンパイルしてみるとt2はコンパイルされていませんでした。 深く理解するにはまだ時間がかかりそうですが、とりあえずtor4kichiさんの仰る通り、Startもしてないのでawaitも出来ないと言うことで納得しました。 Taskは自分には難しいので教えて頂いたサイトも見ながら理解を深めていきたいと思います。 色々詳しく説明して頂きありがとうございました!
guest

0

「だめ」というのがよくわかりませんが・・・

t2 はTaskをコンストラクタから生成しています。そのためTaskが開始されていません。
同様の質問がありましたのでこちらも参考にしてください。
https://ja.ojit.com/so/c%23/1870382

補足

MSDNを見ましたが、タスクの生成と開始を同時に行うTask.Runを使わないケースは以下のみのようです。

Task コンストラクター 

このコンストラクターは、タスクの作成と開始を分離する必要がある高度なシナリオでのみ使用してください。

https://docs.microsoft.com/ja-jp/dotnet/api/system.threading.tasks.task.-ctor?view=net-5.0#System_Threading_Tasks_Task__ctor_System_Action_

投稿2021/02/16 05:34

編集2021/02/16 05:40
ry188472

総合スコア74

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

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

nankoko

2021/02/16 05:42

Task t1 = Task.Delay(1000); もawaitしないと開始されません。 マイクロソフトのドキュメントには、「awaitキーワードはタスクを開始する」と書いてあります。 だったら、t2も実行されそうなものですが
ry188472

2021/02/16 05:49

> Task t1 = Task.Delay(1000); もawaitしないと開始されません。 本当にそうでしたか? t1.Status はどんな値でしたか?
退会済みユーザー

退会済みユーザー

2021/02/16 05:51

> Task t1 = Task.Delay(1000); もawaitしないと開始されません。 そんなことはありません。あなたは一体何が聞きたいの????
退会済みユーザー

退会済みユーザー

2021/02/16 06:01

Microsoft公式にある >await キーワードを使用すると、ブロックしない方法でタスクを開始し という所だけ切り抜いたんでしょうけど >タスクの実行中にスレッドをブロックしないように、このコードを更新することから始めましょう。 await キーワードを使用すると、ブロックしない方法でタスクを開始し、タスクが完了したら実行を継続できます。 翻訳がアレではありますけどきちんと最初から読んでいけばawaitが何やってるかは読めそうですが。 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/async/
nankoko

2021/02/17 04:27

お返事遅くなってすみません。 確かにt1.Statusで確認すると実行されていました。 t2は、コンストラクタから生成されたままで実行されていないと言うことで納得しました。 教えて頂いたurlもとても参考になりました。 皆様ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問