1

スレッド内でのオブジェクト (クラス) の参照に失敗する

別のスレッドで実行し、U/I と通信する必要があるオブジェクト (「vb クラス」) があります。

サンプル コードを使用しても、オブジェクトをスレッド内で実行することはできません。この問題を 2 つの例で示します。最初はフォーム内の関数を呼び出し、完全に機能します。2 番目はオブジェクトを作成し、同じ呼び出しを実行しますが、失敗します。


例 #1 [動作中] (フォーム内で呼び出される)

 Private Delegate Sub FuctionToBeRunInThreadDelegate

 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

    Console.WriteLine("Thread sample within FORM")

    Dim Thread As New System.Threading.Thread(AddressOf FuctionToBeRunInThread)
    Thread.Start()

    Console.WriteLine("Thread sample within FORM completed")

 End Sub

 Public Sub FuctionToBeRunInThread()

    If Me.InvokeRequired Then
        Console.WriteLine("Inside new thread....")
        Me.Invoke(New FuctionToBeRunInThreadDelegate(AddressOf FuctionToBeRunInThread))
    Else
        Console.WriteLine("oFuctionToBeRunInThread")
    End If

  End Sub

関数がフォーム内で呼び出されたときのコンソールへの出力は次のとおりです。 FORM内のスレッド サンプル
FORM 内 の
スレッド サンプルが完了しました。


これは私が期待したものです。スレッドが非同期で開始されました。非常に迅速に終了し、関数はスレッド内にあることを認識しています。




例 2 [動作しない] (今回はオブジェクト内で同じ関数を呼び出す)
2 番目の例では、クラスを含む外部ファイルを使用し、同じ方法でスレッドを作成します。

メインフォームは次のとおりです。

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click

    Console.WriteLine("Thread sample using object started.")

    Dim oEngine As New objTest()
    Dim oThread As New System.Threading.Thread(AddressOf oEngine.oFuctionToBeRunInThread)
    oThread.Start()

    Console.WriteLine("Thread sample using object completed.")


End Sub


クラス定義を含む外部ファイルは次のとおりです。

   パブリック クラス objTest

   プライベート デリゲート Sub oFuctionToBeRunInThreadDelegate()

   Public Sub oFuctionToBeRunInThread()

        If frmInitial.InvokeRequired Then
            Console.WriteLine("新しいスレッド内....")
            frmInitial.Invoke(New oFuctionToBeRunInThreadDelegate(AddressOf oFuctionToBeRunInThread))
        そうしないと
            Console.WriteLine("oFuctionToBeRunInThread")
        終了条件

    サブ終了
   クラス終了

この場合、出力は、関数が別のスレッドで実行されていないことを示しています。以下の通りです

。 オブジェクトを使用したスレッド サンプルを開始しました。
オブジェクトを使用したスレッド サンプルが完成しました。
oFuctionToBeRunInThread



概要:スレッドがオブジェクトを作成するとき、オブジェクトが実際にはスレッド内で実行されていないように見えます。これが強く検証され、証明されている他のより複雑な例がありますが、私の問題の非常に単純なデモンストレーションとしてこれら 2 つを提供しました。

オブジェクトが非同期に実行され、個別に U/I に報告できるように、一連の個々のオブジェクトをスレッドに「所有」させるにはどうすればよいですか?

4

1 に答える 1

1

コードをデバッグした後、frmInitial.InvokeRequired が正しく実行されていないようです。

================================================== =====

だからまた戻ってきました(もちろん解決策があります):

Public Class frmInitial

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Console.WriteLine("event started")

        Dim obj As New ObjTest()
        Dim threadobj As New System.Threading.Thread(AddressOf obj.dosomework)
        threadobj.Name = "debugme"

        'passing the current form reference to the thread function
        threadobj.Start(Me)

        Console.WriteLine("event completed")
    End Sub
End Class

画面のスナップショット

Public Class ObjTest
        Private Delegate Sub dosomeworkDelegate(ByVal f As Form)

        Public Sub dosomework(ByVal f As Form)
            ' Check if the form can be accessed from the current thread.
            If Not f.InvokeRequired Then
                ' Access the form directly.
                Console.WriteLine("delegate executed")
                f.Controls("textbox1").Text = "thread invoked successfuly"
            Else
                ' Marshal to the thread that owns the form. 
                Dim del As dosomeworkDelegate = AddressOf dosomework
                Dim param As Object() = {f}
                Console.WriteLine("executing delegate")
                f.BeginInvoke(del, param)
            End If
        End Sub

End Class

私の数値解析試験のために勉強するよりも、私を信じてください:-)

于 2012-06-09T15:59:15.503 に答える