どうして毎回結果がバラバラなんでしょうか?
しかも6??とかどこから来るんでしょうか??
Taskの事を全然理解していない者です。
基本的な事かもしれませんが・・
調べるための検索キーワードになる、ヒントだけでも教えて頂けたら助かります。
using System; using System.Threading.Tasks; class prog { static void Main() { for(int i=0; i<6; i++){ Task.Run(() => Console.WriteLine(i)); } Console.ReadLine(); } } //結果(毎回バラバラ) //1 //2 //2 //5 //6 //6
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
こちらの回答を参照してください。
C#のTask配列をforでセットしようとするとエラーになる
(追記)
もう少し丁寧な記事を書いてみました。
[C#] ラムダ式内でラムダ式外のループカウンタ変数を使用すると危険
投稿2021/01/25 16:59
編集2021/01/29 01:01退会済みユーザー
総合スコア0
0
既に質問は閉まっていますが、下記についてこうプログラムが動きうるであろうストーリーの1例をシーケンス図で表現してみたので、載せておきます。
//結果(毎回バラバラ)
//1
//2
//2
//5
//6
//6
下記のタイミングに注目してください。
- Task.Run をするタイミング
- 各タスクが i を取得するタイミング
- i を Console.WriteLine で出力するタイミング
この図を通して伝えたいことは、まず Task を利用する事で各タスクやタスク外の処理がそれぞれ並列に動くことです。
そして、タスクに作業を配置(Task.Run)するタイミングと実際にタスクが処理(このプログラムでいうConsole.WriteLine)を行うタイミングは別であるということです。
少なくともそれ等のタイミングの間には隙間が存在するので、Task.Run したタイミングと Console.WriteLine したタイミングで i の値が変化することは至って普通の事象です。
また、タスクに委譲した作業が実際に処理されるタイミングはスレッドプールのみぞ知る、です。
スレッド プールとタスク
スレッドプールのスレッドが足りなくて新たなスレッドを内部で生成する場合なんかは時間がかかるかもしれません。スレッドの生成にはコストがかかります。
マネージド スレッド プール
スレッド プールの最小値に達すると、追加のスレッドが作成されるか、いくつかのタスクが完了するまで待機状態になります。
投稿2021/01/29 04:41
総合スコア2663
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/29 23:35
0
そもそも、別タスクを非同期実行させるためにTask.Runさせるんでしょう。
それを忘れてはいけません
() => Console.WriteLine(i)
のタスクは、Task.Runで実行されるわけでなく、ただ非同期実行させるために登録されるだけです
それが実際に実行されるのはいつか、ってのを考えてみればどうでしょう
投稿2021/01/25 22:36
総合スコア88038
0
ベストアンサー
6が出力される原因はforループを抜けて最後にi++された後のiが参照されて出力されているからです。
Task.Run(() => ...)
が実行された時点で別スレッドでの処理が開始され、Main()
が動作しているスレッドではない別のスレッドで非同期的にConsole.WriteLine(i)
が実行されます。
[追記]質問の方にTask/非同期以前に変数の生存期間に対する理解不足があると認識できてませんでした。以下の回答は取り消したいと思います。
Task.Run
で非同期処理させた内容を待機するにはasync/await
を利用することで非同期処理を同期的に扱うことができます。
class prog { static async Task Main() { for(int i=0; i<6; i++){ await Task.Run(() => Console.WriteLine(i)); } Console.ReadLine(); } }
というように非同期での出力処理をawait
で待機させることで0~5まで順番に出力させられます。
投稿2021/01/26 05:03
編集2021/01/30 04:35総合スコア769
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/01/26 06:02
2021/01/28 09:22
退会済みユーザー
2021/01/29 02:02
2021/01/29 02:30
2021/01/29 03:34
2021/01/29 04:10
2021/02/01 04:42
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/29 03:20
2021/01/29 04:51 編集
退会済みユーザー
2021/01/29 05:17 編集
2021/01/29 05:20
退会済みユーザー
2021/01/29 05:26 編集
2021/01/29 23:48
2021/01/29 23:48
退会済みユーザー
2021/01/30 00:57
2021/01/30 02:57
退会済みユーザー
2021/01/30 03:18
2021/01/30 07:24
退会済みユーザー
2021/01/30 09:00
2021/02/01 04:37
退会済みユーザー
2021/02/01 08:18 編集
2021/02/01 08:14