2012年10月22日月曜日

マルチスレッドにした覚えはないのに「有効ではないスレッド間の操作」でエラー

また思い出したのでメモ。

VB.NET(VS2010)で、シリアル通信接続のカードリーダーからカードの情報を読み込んでなんやかんや、というアプリケーションを作成していました。
カードリーダーとかよくわからんので、とりあえず、読み込んだデータをフォームに表示してみることに。カードリーダーの読み書きについては出来合いのライブラリがあるので、リード成功イベントのところで、読み込んだ値(String)をフォームのテキストボックスのTextプロパティにセットして表示するようにしました。ところが、Textプロパティに値をセットするところで、

有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'txtCardData′ がアクセスされました。

と出てしまってうまくいきません。txtCardDataというのがテキストボックスで、このTextプロパティに値を代入しようとしたところでエラーになります。
例によってググるとwこのエラーは、別のスレッドからUIコントロール(この場合、フォームに貼ってるテキストボックス)にアクセスしようとしたときに出るらしいです。でも別にマルチスレッドなコードは書いてないのですが……。

さらにググってわかったのは、シリアル通信の受信イベントは別スレッドで立ち上がるとかそういう制限(?)があるようです。自分ではマルチスレッドなコードを書いてなくても、勝手にマルチスレッドになってるらしい。となると、このコードのままじゃどうしたって駄目なのか……。

結局、リード成功のイベントからというのが駄目なんだから他からならいいだろうということで、ここのイベントからはクラスのメンバ変数に値を渡すだけにして(UIコントロールの操作をしなけりゃいいので変数セットとかはできる)、タイマ回してその変数を拾ってテキストボックスに表示させるようにしました。なんか回りくどいように思ったけど、シリアル通信関係のアプリケーションではタイマ監視して処理させるというのはなんかお決まりの処理らしいので、これでいいのか。

0 件のコメント: