【アズレン完全攻略wiki】Invokeメソッドを使ったサブスレッドからのフォーム操作
はじめに
どぅも~モナ↑ーでぇす。ハイ、というわけでね、C#の方やっていきたいと思いまスゥ...おま○け
別スレッドからフォームを操作したいということがあって【初心者必見!】みたいなサイト見ながら頑張ってプログラム書いてたんだけどうまくいかなかった。別スレッドで行った処理の結果をフォームに表示させるみたいな。
ちなみに思い描いてるものとしては画面右のスタートボタン押すと左側のラベルが1,2,3,4,......100までカウントアップしていくって感じのものです。
ソースは↓です。
public partial class Form1 : Form { delegate void CountDlg(); public Form1() { InitializeComponent(); } private void StartButton_Click(object sender, EventArgs e) { var thread = new Thread(new ThreadStart(CountThread)); thread.Start(); } private void CountThread() { CountDlg count = () => { for (var i = 1; i <= 100; i++) { label1.Text = i.ToString(); Thread.Sleep(100); } }; this.Invoke(count); } }
ちなみにこれを動かすとスタートボタン押した瞬間Formアプリケーションくん迫真の”応答なし”で応戦してくれます。嬉しい。(嘘です。めっちゃキレそうになりました。)そしていきなり表示が100になって頭が爆発します。
そしてセコセコ修正したのが↓
public partial class Form1 : Form { delegate void CountDlg(); public Form1() { InitializeComponent(); } private void StartButton_Click(object sender, EventArgs e) { var thread = new Thread(new ThreadStart(CountThread)); thread.Start(); } private void CountThread() { for (var i = 1; i <= 100; i++) { UpdateText(i); Thread.Sleep(500); } } private void UpdateText(int value) { if (this.InvokeRequired) { this.Invoke(new CountDlg(() => label1.Text = value.ToString())); } else { label1.Text = value.ToString(); } } }
デリゲートが参照する処理の中ではラベルの更新だけ行ってカウントアップの処理は
CountThreadの中で行うようにしたらうまくいきました。
なんででしょうかねぇ...不思議ですねぇ...
Visual Studioさんが便利すぎてフォームアプリの内部的なことをあまり理解できてないのかなというのがすごく実感できたので暇なときに(いつ??)調べようと思いました。
本編
そろそろ俺を試そうとするのはやめませんか?
lv65程度の敵しかわかないマップを60週もさせられる俺の気持ちわかるか?言ってることわかるか??
まぁ”廻る”んですけどね。
ちょうどシャングリラのレベルが良い感じなので、こいつのレベリングなんだと自分に言い聞かせながら周回しているような状況です。
とはいってもかなりしんどいので次のイベントもゲロマズだったらシャドウバースガチ勢にジョブチェンジするかもしれません。
ほなまた...
追伸
じろうさんのブログにてもなーのあれこれを紹介していただきました。ありがとうございます。