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

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

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

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

解決済

Task.Factory.StartNew(() => {})の中で変数が勝手に書き換わってしまう原因が知りたい。

samidare_chan
samidare_chan

総合スコア252

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

1回答

-4評価

0クリップ

325閲覧

投稿2022/07/29 06:46

提示コードの///コメント部内のコードですがfor文のループ変数jが勝手に書き換わってしまいます、コンソールログ参照。これはなぜでしょうか?filePathList.Count の値は確かになのですが、書き換わる原因が知りたいです。

コンソールログ
ああああ 1 1 うううう 0 いういいい 1 例外がスローされました: 'System.ArgumentOutOfRangeException' (System.Private.CoreLib.dll の中) 型 'System.ArgumentOutOfRangeException' の例外が System.Private.CoreLib.dll で発生しましたが、ユーザー コード内ではハンドルされませんでした Index was out of range. Must be non-negative and less than the size of the collection.
ソースコード

cs

private async void buttonConvert_Click(object sender, EventArgs e) { if(folderBrowserDialogSavePath.SelectedPath != "") { if(filePathList.Count > 0) { Debug.WriteLine("ああああ"); for (int i = 0; i < filePathList.Count; i++) { string file = Path.GetFileName(filePathList[i]); file = Path.ChangeExtension(file,".jpeg"); file = folderBrowserDialogSavePath.SelectedPath + "\\" + file; filePathList_Save.Add(file); } buttonConvert.Enabled = false; Stopwatch sw = new Stopwatch(); sw.Start(); var slim = new SemaphoreSlim(5); Debug.WriteLine(filePathList.Count); Debug.WriteLine(filePathList_Save.Count); ////////////////////////////////////////////////////////////////////////////////////////////// for(int j = 0; j < filePathList.Count; j++) { Debug.WriteLine("うううう " + j); taskList.Add(Task.Factory.StartNew(() => { Debug.WriteLine("いういいい " + j); Process(slim, filePathList[j],filePathList_Save[j]); this.Invoke((Action)(() => { progressBar_float += progressBarPerFile; progressBar.Value = (int)progressBar_float; })); })); } ////////////////////////////////////////////////////////////////////////////////////////////// await Task.WhenAll(taskList); buttonConvert.Enabled = true; slim.Dispose(); progressBar.Value = 0; sw.Stop(); TimeSpan ts = sw.Elapsed; Debug.WriteLine("convert time: " + ts.TotalSeconds +"."+ ts.Milliseconds); } else { MessageBox.Show("NO input file(s)", "", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show("\n\n NO set save path", "", MessageBoxButtons.OK, MessageBoxIcon.Error); } }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

YAmaGNZ

2022/07/29 07:03

非同期で実行されているからでは?
kikukiku

2022/07/29 07:23

jのインスタンスは下記で作成されています。 for(int j = 0; j < filePathList.Count; j++) Debug.WriteLine("いういいい " + j);にて 複数存在する別スレッドから共通同じインスタンスjにアクセスしています。 別スレッドが動作中も、UIスレッド上のbuttonConvert_Clickは動作し続けるので jはカウントアップされます。 別スレッドの動作するタイミングによって、 変数jが1のときにjを参照すれば1になるし、 変数jが2のときにjを参照すれば2になるということ。 なので下記のように変数kのインスタンスを毎回作成してあげれば 別スレッドから個別のインスタンスkを参照するようになるので 期待する動作をするのではないか。 Debug.WriteLine("うううう " + j); var k = j; taskList.Add(Task.Factory.StartNew(() => { Debug.WriteLine("いういいい " + k);
samidare_chan

2022/07/30 03:55

質問ですが "別スレッドの動作するタイミングによって、"についてもうちょっと詳しく聞いてもいいですか? "buttonConvert_Clickが動作し続ける"というところの意味がわかりません。
kikukiku

2022/07/31 23:51

うーん、上記の文章でわからないとなると、 図を書いて説明が必要なのかもですが 申し訳ないのですが、面倒すぎて説明の気力が湧きません。 別スレッドの起動ですが、別スレッドを起動する命令が実行されても 実際にはすぐ実行されるのか、時間をおいてから実行されるのかは 保証がないため、早く実行されれば、カウントが1になることもあるし、 遅く実行されれば、カウントが2になることもあるでしょう。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。