RCIE-ジャンクのコード屋

主に自分のためにコーディングのTIPSを蓄積しています。

(C#)フォームのバックグラウンドで重い処理をしながら、UI を変更したい

解説

 フォームアプリの Click イベントの中で、重い処理をしてはいけません。UI がフリーズしてしまいます。その時は、別のスレッドでバックグラウンド処理(非同期処理)を行います。

 しかし、別スレッドから UI を操作してはいけません。例外が発生してしまいます。その時は、UI スレッドに頼んでやってもらいます。

 このような非同期処理のモデルとして、ボタンを押すと、一秒ごとに表示が変化するコードの例を紹介します。

前提

  • フォームの中にボタン [button1] がある。
  • button1 をクリックした際のイベント処理が [button1_Click] である。

コード

private void button1_Click(object sender, EventArgs e) {
	button1.Text = "実行中"; // すぐにUIを変更する
	Task.Run(() => {
		System.Threading.Thread.Sleep(1000); // 何かしらの重い処理
		BeginInvoke((MethodInvoker)delegate () {
			button1.Text = "実行中…"; // 処理の途中でUIを変更する
		});
		System.Threading.Thread.Sleep(1000); // 何かしらの重い処理
		BeginInvoke((MethodInvoker)delegate () {
			button1.Text = "実行中……"; // 処理の途中でUIを変更する
		});
		System.Threading.Thread.Sleep(1000); // 何かしらの重い処理
		BeginInvoke((MethodInvoker)delegate () {
			button1.Text = "終了"; // 処理の終了時にUIを変更する
		});
	});
}