Windowsフォームアプリでは、Task.Run()など別スレッドから、メインスレッドのフォームコントールを操作すると、「System.InvalidOperationException: ‘有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール がアクセスされました。’」Exceptionが発生しますが、Invoke()を通すことで解消します。
Invoke()を通すことで解消します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private void button3_Click(object sender, EventArgs e) { Task.Run(() => { var value = "ccccc"; Invoke(() => { textBox1.Text = value; }); }); } |
ソースコードはGitHubで公開しています。
ソースコード構成
今回使った Visual Studio プロジェクト テンプレートは、Visual Studio 2022 + .NET 6.0 の Windowsフォームアプリです。
テンプレートに対して、下記の処理を加えました。
ソースコード変更内容を解説
3パターンの実装で、テキストボックスに値を設定するボタンを3つ追加。
・button1は、メインスレッドからメインスレッドへ値を設定し、正常終了。
・button2は、別スレッドからメインスレッドへ値を設定し、Exception発生
・button3は、別スレッドからメインスレッドへ Invokeを通して値を設定し、正常終了。
/Form1.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
namespace WinFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { textBox1.Text = "aaaaa"; } private void button2_Click(object sender, EventArgs e) { Task.Run(() => { textBox1.Text = "bbbbb"; }); } private void button3_Click(object sender, EventArgs e) { Task.Run(() => { var value = "ccccc"; Invoke(() => { textBox1.Text = value; }); }); } } } |
コメント