簡単に言えば、スレッドを使用しているときに、invoke やデリゲートを使用して別のクラスからユーザーフォームを更新する方法を理解しようとして、私はかなりの時間を費やしています。経験豊富な人にとっては、ばかげて明らかなことだと確信しています。おそらくデリゲートが必要であることはわかっていますが、私のすべての努力は、メインスレッドから呼び出されたときにのみ機能するようです。半日インターネットを見て回ったのですが、何かわからないことがあります。
例として、いくつかの疑似コードを次に示します。
このオプションは機能します:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)
t1.IsBackground = True
t1.Start(100)
End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Count(CInt(Max))
End If
End Sub
Private Sub SetLabelText(ByVal text As String)
If Label1.InvokeRequired Then
Label1.Invoke(New Action(Of String)(AddressOf SetLabelText), text)
Else
Label1.Text = text
End If
End Sub
Private Sub Count(ByVal Max As Integer)
For i = 1 To Max
SetLabelText(CStr(i))
Threading.Thread.Sleep(200)
Next
End Sub
End Class
これ(わずかに異なるバリエーションの私の1000の努力の1つ)はそうではありません。実際には、この例では、サブルーチンの 1 つを独自のクラスに分離しようとしましたが、それ以外は、作成できるものと同じです。
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t1 As New Threading.Thread(AddressOf Count)
t1.Start(100)
End Sub
Private Sub Count(ByVal Max As Object)
If TypeOf Max Is Integer Then
Dim class2 As New class2
class2.Count(CInt(Max))
End If
End Sub
Private Delegate Sub SetTextBoxTextInvoker(text As String)
Sub SetLabelText(ByVal text As String)
'or me.label1, form1.label1 or anything else I can try!
If Me.InvokeRequired Then
Me.Invoke(New SetTextBoxTextInvoker(AddressOf SetLabelText), _
text)
Else
Me.Label1.Text = text
End If
End Sub
End Class
Public Class class2
Sub Count(ByVal Max As Integer)
For i = 1 To Max
form1.SetLabelText(CStr(i))
Threading.Thread.Sleep(200)
Next
End Sub
End Class
私が知る限り、Sub "SetLabelText" 内の invokerequired の if ステートメントは決してトリガーされないようです。私の最善の推測は、invokerequired パラメータをチェックするときに、ユーザーフォームを正しく参照していないということですか? または、デリゲートに何か他のものを与える必要がありますか? 私は、間違っているかもしれない何百万もの小さな変数をいじることにイライラしています。事前にサポートを提供していただきありがとうございます。さらに情報が必要な場合はお知らせください。