dポイントプレゼントキャンペーン実施中!

VB2005でデリゲートというものを始めて使っています。

いま困っているのは、メインスレッドのテキストコントロールのTextプロパティに、別のスレッドからデータをセットする場合、デリゲートという機能を使わないといけないということで、以下のようにしています。
画面上には別スレッドで書きこみたいTextBoxコントロールが沢山あり、
個々に(1)を記述しないといけないのでしょうか?
txtTest部分の名前が違うだけですが・・・
デリゲードに関して初めて使っているのであまり理解できていませんが、数が多いと
面倒なので何か方法があるのではないか、質問しました。
詳しい方教えて下さい。
そもそも、別スレッドの書き込みでデリゲートを使う方法は駄目なのでしょうか?


'デリゲートの定義
Delegate Sub dlgWriteText(ByVal text As String)


'txtTestに書き込む ----- (1)   セットするコントロール毎にこれが必要???
Private Sub DlSettxtUserName(ByVal text As String)
  Me.txtTest.Text = Text
End Sub


'別スレッド部分

dim data as String = "別スレッドでデータセット"

'別スレッドで書きこむ
Me.txtTest.BeginInvoke(New dlgWriteText(AddressOf dSetTest), data)


よろしくお願いします。

A 回答 (1件)

> セットするコントロール毎にこれが必要???


 もちろんそれを回避するテクニックは色々あるのですが、最初はそこから始めてください。ここを理解しないで応用編に進むと後で絶対に泣きます。もし、今仕事で開発してて、時間がねぇ原理は要らねぇ動くモノだけよこせという事態なのであれば・・・・むしろ時間が無いなら確実に動く今の形を一生懸命実装する方が最終的に泣かなくてすむかと。

 ちなみに、基本形として一般的には以下のように記述します。

Private Delegate Sub dlgWriteText(ByVal text As String)
Public Sub DlSettxtUserName(ByVal text As String)
 If Me.txtTest.InvokeRequired Then ' Delete
  Static Dim d As dlgWriteText = New dlgWriteText(AddressOf Me.DlSettxtUserName)
  Me.txtTest.Invoke(d, text)
  Return
 End If
 Me.txtTest.Text = text
End Sub

 これで、フォームスレッドの中からでも外からでもDlSettxtUserNameを呼ぶとtxtTestに文字をセットし、かつ必要があれば勝手にInvokeしてくれます。必要かどうかの判断も.Net Frameworkが自動でやってくれるのでとっても楽チン。

 応用編としては、最も安直で泥臭いモノだとdlgWriteTextにIntegerの引数を一つ増やしてそれの値によってコントロールを選択する、とかね。第二引数にテキストボックスを直接食わせても良いんですけど、まずはDelegate(というかInvoke)について後ろで動いているカラクリを理解する事です。後、BeginInvokeは非同期Invokeを行うもので、使うならきちんとEndInvokeを呼び出してあげるべきです。今回の文字列一つコピーのような場合は同期InvokeのInvokeを使うのが良いと思います。

この回答への補足

|ご忠告、ありがとうございます。
なるほど、意識して使わなくても済むように、一元化するのですね。


応用編で申し訳ないのですが、こういう事でしょうか?
noを引数の前に入れています。

Private Delegate Sub dlgWriteText(Byval no as Integer, ByVal text As String)

Public Sub DlSetText(Byval no as Integer, ByVal text As String)
Select case no

case 1: 'txtTestの場合
 
If Me.txtTest.InvokeRequired Then ' Delete
   Static Dim d As dlgWriteText = New dlgWriteText(no, AddressOf Me.DlSettxtUserName)
   Me.txtTest.Invoke(d, no, text)
   Return
  End If
  Me.txtTest.Text = text

case 2: 'textExampleの場合

'省略

End Select


End Sub


ここで疑問が2つ出てきました。
(1)Static Dim dのところで、なぜStaticとする必要があるのか
(2)非同期Invokeはどういう時に使われるのでしょうか?サンプルもあれば助かります。

よろしくお願いいたします。

補足日時:2009/04/16 01:36
    • good
    • 0

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