重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【終了しました】教えて!goo新規会員登録

■.NETモジュールプロジェクト(DLL)

Public Class MyClass
  Public Event hoge( ByVal sender As Object, ByVal e As EventArgs )
  Private WithEvents Timer As Timers.Timer
  Private Sub New()
    Timer = New Timers.Timer : Timer.Interval = 10 : Timer.Start()
  End Sub
  Private Sub fuga( ByVal sender As Object, ByVal e As EventArgs ) Handles Timer.Elapsed
    RaiseEvent hoge( Me, New EventArgs ) ' 一定時間ごとにイベントを発生させる
  End Sub
End Class

■上の.NETモジュールを参照している Windows Form アプリケーションプロジェクト(EXE)

Public Class Form1
  Private WithEvents foo As MyClass.MyClass
  Public Sub New()
    InitializeComponent()
    foo = New MyClass.MyClass
  End Sub
  Private Sub bar() Handles foo.hoge
    TextBox1.Text = "baz" ' TextBox1 は デザイナで Form1 に貼り付け済み
  End Sub
End Class

という 2 プロジェクトを含むソリューションを作成しました。実行すると、

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

というエラーが出てきます。

foo が MyClass ではなく、system.windows.forms.dll などに入っている Button や Form といったコントロールの場合は、上記の bar() のような書き方でもスレッドセーフに扱えるので、MyClass もForm1 のコードを修正する事なく、利用できたらなと思っています。

その場合、どのように MyClass を書けばいいでしょうか。環境は VS2008 で、.NET2.0 ベースです。

A 回答 (1件)

別スレッドで動作するタイマーによってイベントが発生するのが仕様なのですから,


それにあわせて使う側が処理します。
ControlをUIスレッド以外から扱うことはできません。

具体的には,barの中でControl.InvokeRequiredが真であれば,
Control.InvokeまたはControl.BeginInvokeを呼び出して,
その中でControlへアクセスする,というものです。


ButtonやFormのイベントは,UIスレッド上で発生します。
そのため,スレッドの問題は関係してきません。
    • good
    • 0
この回答へのお礼

遅くなりましたが回答ありがとうございました

お礼日時:2011/10/26 15:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!