なべひろBlog

プログラミングをメインに仕事に関するアレコレを発信しています。

WinFormsのコントロールを別Taskで動かす

今時WinFormsかよ!と言わないでください。

サクサクっとテスト用アプリなんか作る時には一番簡単です。

動作も軽いですし、ネットを検索すれば情報は山のように出てきます。

いつからか忘れましたが.NET Frameworkも別タスク(スレット?)での処理が楽になりましたね。

キーワードは「Task」「async」「await」でしょうか。

スレッド(Thread)との違いを解説してあるサイトもありますので興味のある方は検索してみてください。

分かりやすい解説はたくさんあります。

私がTaskを使う訳は通信を含む背後で多くの処理を行う時などで、UIが固まって使用者が「!??」とならないようにするためってのが多いです。

これは別に書いた

にも当てはまる事かもしれません。

他にも色々使い道はありますが、本題から外れますので割愛します。

Taskを使って時々「あっ!」となったり初めてだと「何で?」となるのがTask内でのコントロール制御です。

Taskの中でTextBoxやLabelのTextプロパティに文字列をセットすると例外でアプリが終了してしまいます。

Debugでも何の例外が出たのかイマイチなメッセージなので、最初は何の事なのか分かりませんでした。

原因はUIとは別のスレッドでUIの操作はできないって事です。

その対策としては

this.Invoke((Action)(() => label1.Text = Count.ToString()));

コントロールの制御記述に一手間加えるだけでOKです。

複数の処理をやる場合は

this.Invoke((Action)(() =>
{
    label1.Text = Count.ToString();
}));

のように{}内に複数の記述も可能です。