この記事は、Windows フォームアプリケーション (.NET Framework)の話です。 Windows WPFアプリ (.NET Framework) の場合
HeavyTask_Error だと
System.InvalidOperationException: '有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'Othersbutton' がアクセスされました。'
というエラーが出る。
正しくUIを操作するには、HeavyTask_Fixed のように修正する。delegate
に対して Invoke
で呼び出せばよい。
//エラーが出る Othersbutton.Enabled = false; //修正後 {内は複数行でも可} Invoke(new Action(() => { Othersbutton.Enabled = false; }));
コード全体は以下の通り
using System; using System.Threading.Tasks; using System.Windows.Forms; <200b> namespace WindowsFormsApp1 { public partial class Form1 : Form { bool stop = false; public Form1() { InitializeComponent(); } void HeavyTask_Error() { Othersbutton.Enabled = false; for (int i = 0; i < 30; i++) { System.Threading.Thread.Sleep(100); if (stop) break; label1.Text = i.ToString(); } if (stop) { label1.Text = "Stop!"; } else { label1.Text = "Completed!"; } Othersbutton.Enabled = true; } void HeavyTask_Fixed() { Invoke(new Action(() => { Othersbutton.Enabled = false; })); for (int i = 0; i < 30; i++) { System.Threading.Thread.Sleep(100); if (stop) break; Invoke(new Action(() => { label1.Text = i.ToString(); })); } if (stop) { Invoke(new Action(() => { label1.Text = "Stop!"; })); } else { Invoke(new Action(() => { label1.Text = "Completed!"; })); } Invoke(new Action(() => { Othersbutton.Enabled = true; })); } private void StartError_Click(object sender, EventArgs e) { stop = false; Task.Run(() => HeavyTask_Error()); } private void StartFixed_Click(object sender, EventArgs e) { stop = false; Task.Run(() => HeavyTask_Fixed()); } private void Stop_Click(object sender, EventArgs e) { stop = true; } } }
検索用 thread forms