- PR -

異なるスレッドがらTreeViewのノードを追加するには

1
投稿者投稿内容
HIRO
常連さん
会議室デビュー日: 2004/10/28
投稿数: 41
投稿日時: 2005-02-03 11:35
マルチスレッド環境においてフォームとは別のスレッドからTreeViewにノードを追加する際にエラーが発生します。
「このコントロールで実行されている動作は、間違ったスレッドから呼び出されています。この動作を実行するには、Control.Invoke または Control.BeginInvoke を使って正しいスレッドにマーシャリングしてください。」
言っている事はわからないこともないのですが、対処の方法がわかりません。デリゲートを使用すればできそうな気はするのですが、使い方がいまいちよくわかりません。以下はそのエラーが発生するコードです。

Dim testThread As New System.Threading.Thread(AddressOf test)

Private Sub test()

Try
TreeView1.Nodes.Add("testnode")
Catch ex As Exception
MsgBox(ex.Message)
End Try

End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

testThread.Start()

End Sub

Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed

testThread.Abort()

End Sub

わかられる方ご教授お願いします。
にしざき
ぬし
会議室デビュー日: 2003/06/30
投稿数: 304
投稿日時: 2005-02-03 11:43
メッセージの通り、対象のコントロールのスレッド上からでないと操作してはいけません。
方法も書かれているとおり、対象のコントロールに対して Invoke メソッドを実行します。
コード:
Private Sub Test()
  If TreeView1.InvokeRequired Then
    TreeView1.Invoke(AddressOf Test)
  Else
    TreeView1.Nodes.Add("testnode")
  End If
End Sub


VB.NET 構文は知らないので、特に AddressOf のあたりが適当ですが。
HIRO
常連さん
会議室デビュー日: 2004/10/28
投稿数: 41
投稿日時: 2005-02-03 12:13
回答ありがとうございます。
実際教えていただいたコードを使ってみたのですが、AddressOfの部分でエラーになってしまいます。

「'System.Delegate' は、デリゲート型でないため、'AddressOf' 式を 'System.Delegate' に変換できません。」

MSDNでInvokeを見てみたのですが、いまいちピンとこないです。お恥ずかしい・・・
にしざき
ぬし
会議室デビュー日: 2003/06/30
投稿数: 304
投稿日時: 2005-02-03 14:36
やはりエラーでしたか。じゃ、先ほどのコードを
コード:
(どこかで)
Private Delegate Sub NoParamDelegate()

(修正点)
  If 〜 Then
    NoParamDeleagate dele = AddressOf Test
    TreeView1.Invoke(dele)
  Else


で動くのかなぁ…
C#でいえば、
コード:
private delegate void NoParamDelegate();
private void Test() {
  if (TreeView1.InvokeRequired) {
    TreeView1.Invoke(new NoParamDelegate(Test));
  } else {
    TreeView1.Nodes.Add("testnode");
  }
}


なんですが。
HIRO
常連さん
会議室デビュー日: 2004/10/28
投稿数: 41
投稿日時: 2005-02-03 14:50
にしざき様
回答ありがとうございます。
以下のコードでうまくいきました。本当にありがとうございました。

Private Delegate Sub NoParamDelegate()

If TreeView1.InvokeRequired Then
TreeView1.Invoke(New NoParamDelegate(AddressOf test))
Else
TreeView1.Nodes.Add("testnode")
End If
1

スキルアップ/キャリアアップ(JOB@IT)