別スレッドで動くC++.NETで作成したライブラリから発生するイベントを受けて、自作ビューワコントロールに「タブを追加して複数のイメージを各タブに表示」という処理を行うと、下記のエラーが発生した。
System.ArgumentExceptionのハンドルされていない例外が system.windows.forms.dll で発生しました。 追加情報 : あるスレッドで作成されたコントロールに対して、 別のスレッドのコントロールを親にすることはできません。
最初は何のことだか?という感じだったが、結局、
- 別スレッドで動くライブラリにAddHandlerで関連付けられたイベント処理は、主フォームとは別のスレッド管理下におかれてしまう。
- スレッド間で、相手が管理するオブジェクトに対する命令実行は制限される。
ということらしい。スレッド系の処理は、正直「未経験」(←仕事を始めて、ずーっとVB5.0、VB6.0の世界だけだったから)。というわけでこういうのはすんごく苦手なのだが、以下のサイトを参考にしてうまく切り抜けられた。
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vbcon/html/vbtskmanipulatingcontrolsfromthreads.asp
'呼び出したいメソッドと同じシグネチャのデリゲートを宣言 Public Delegate Sub AddImages_Delegated(ByVal Files As ArrayList) '別スレッドの監視ライブラリからのメッセージ受信 Private Function EventReceive(ByVal EventType As Integer) As Integer Dim FileNames As New ArrayList FileNames.Add("c:\testdata.jpg") FileNames.Add("c:\transalp.jpg") '↓本来やりたかった処理 'MainViewer.AddImages(FileNames) '↓代わりに実行する処理 MainViewer.Invoke( _ New AddImages_Delegated(AddressOf MainViewer.AddImages), _ New Object() {FileNames}) End Function
MainViewerはプロジェクト内に組み込まれたユーザーコントロールで、ファイル名を含んだArrayListを元に、複数のイメージをタブで重ねて同時表示する。この表示処理内部では、すでにあるタブに、新しく生成したタブを動的に追加するという処理が含まれており、エラーはそこで発生していた。

インサイドWINDOWS 第6版 上 (Microsoft Press)
- 作者: Mark E. Russinovich,David A. Solomon,Alex Ionescu,株式会社クイープ
- 出版社/メーカー: 日経BP社
- 発売日: 2012/10/04
- メディア: 単行本
- 購入: 2人 クリック: 78回
- この商品を含むブログ (7件) を見る