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

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

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

解決済

C# this.Invoke((Action)(() =>が動作しない原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

1回答

0リアクション

0クリップ

564閲覧

投稿2022/07/28 10:27

提示コードですが buttonConvert_Click関数の内部ですがthis.Invokeにコードが推移しませんこれはなぜでしょうか?

参考サイト:https://www.codeproject.com/Questions/66345/Invoking-not-working

cs

private void Process(SemaphoreSlim slim,string path,string ext) { slim.Wait(); string file = Path.ChangeExtension(path, ext); ImageMagick.MagickImage img = new ImageMagick.MagickImage(path); img.Write(file); img.Dispose(); slim.Release(); } List<Task> taskList = new List<Task>(); private void buttonConvert_Click(object sender, EventArgs e) { Stopwatch sw = new Stopwatch(); sw.Start(); var slim = new SemaphoreSlim(3); foreach (string path in filePathList) { taskList.Add(Task.Factory.StartNew(() => { Process(slim, path,".jpeg"); Debug.WriteLine("ああああ"); this.Invoke((Action)(() => { progressBar_float += progressBarPerFile; progressBar.Value = (int)progressBar_float; Debug.WriteLine("いいい"); })); Debug.WriteLine("aaaaaaaaaaaaaaa" + progressBar.Value); })); } Task.WhenAll(taskList).Wait(); slim.Dispose(); progressBar.Value = 0; sw.Stop(); TimeSpan ts = sw.Elapsed; Debug.WriteLine(ts.TotalSeconds +"."+ ts.Milliseconds); }
コンソールログ
'HEIC_Converter.exe' (CoreCLR: clrhost): 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.7\System.Runtime.InteropServices.RuntimeInformation.dll' が読み込まれました。シンボルの読み込みをスキップしました。モジュールは最適化されていて、デバッグ オプションの [マイ コードのみ] 設定が有効になっています。 ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ ああああ スレッド 0x1b14 はコード 0 (0x0) で終了しました。 ああああ ああああ ああああ ああああ ああああ プログラム '[9508] HEIC_Converter.exe' はコード 4294967295 (0xffffffff) で終了しました。

以下のような質問にはリアクションをつけましょう

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

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/07/28 12:34

こちらの質問が複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました。

KOZ6.0

2022/07/28 23:48 編集

Task.WhenAll(taskList).Wait(); でメッセージループをブロックしているので Invoke が進みません。 別スレッドで待機するなり、非同期メソッドにするなりしてください。
kikukiku

2022/07/28 23:40

KOZ6.0さんの回答がまさに的を得た回答だと思います。 ただ、質問者さんは理解できていないような気がするのでちょっとだけ解説付けます。 ①UIスレッド  buttonConvert_Clickは、名称からボタンの処理だと思うので、  これはUIスレッドで動作します。  その後、Task.WhenAll(taskList).Wait();にて別スレッドの終了を待ちます。  このとき、UIスレッドでの処理は終了していない状態になっています。 ②別スレッド  Task.Factory.StartNewにて別スレッドを起動しています。  この別スレッド内からthis.Invokeを実行することで  UIスレッドが空くまで待機しています。  このとき、別スレッドはの処理は終了していない状態になっています。 ①は②の終了を待ち、②は①の終了を待つことになっているため、 いわゆるデットロックの状態になっています。
kikukiku

2022/07/28 23:56

Task.WhenAll(taskList).Wait();は同期的に待機します。 つまり、UIスレッドが終了していない状態。 await Task.WhenAll(taskList);は非同期的に待機します。 内部的にここから再開することを覚えておいて、一旦UIスレッドを終了します。 別スレッドの終了を検知したら、再開ポイントに戻って 再びUIスレッドの続きの処理を続行します。
kikukiku

2022/07/28 23:59

Wait()使うなと良く掲示板などで書かれていますが まさにその状態ですね。
退会済みユーザー

退会済みユーザー

2022/07/29 04:15

なるほど[この別スレッド内からthis.Invokeを実行することで  UIスレッドが空くまで待機しています。] という説明文ですがこれはthis.InvokeでUIスレッドが空くまで待機してから処理するという意味なのでしょうか?

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

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

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

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

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