1

在线程中引用对象(类)失败

我有一个需要在单独的线程上运行并与 U/I 通信的对象(“vb 类”)。

即使使用示例代码,我也无法让对象在线程中运行。我用两个例子来说明这个问题。第一个在表单中调用一个函数,它工作得很好。第二个创建一个对象并执行相同的调用,但失败了。


示例 #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

当在
表单
调用函数时,控制台的输出是


这是我所期望的。线程已异步启动。很快就结束了,函数知道它在一个线程中。




example #2 [non-working](调用相同的函数,但这次是在一个对象中)
在我的第二个示例中,我使用一个包含类的外部文件并以相同的方式创建线程。

这是主要形式:

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

   私有委托子 oFuctionToBeRunInThreadDelegate()

   公共子函数ToBeRunInThread()

        If frmInitial.InvokeRequired Then
            Console.WriteLine("在新线程内......")
            frmInitial.Invoke(新的 oFuctionToBeRunInThreadDelegate(oFuctionToBeRunInThread 的地址))
        别的
            Console.WriteLine("oFuctionToBeRunInThread")
        万一

    结束子
   结束类

在这种情况下,输出表明该函数没有在单独的线程中运行。如下:

使用对象启动的线程示例。
使用对象的线程示例已完成。
oFuctionToBeRunInThread



摘要:当线程创建对象时,看起来对象实际上并未在线程内部运行,否则 form.InvokeRequired 将为真。我还有其他更复杂的例子,这些例子得到了强有力的验证和证明,但我提供了这两个作为我的问题的一个非常简单的演示。

我怎样才能让一个线程“拥有”一系列单独的对象,以便这些对象异步运行并且可以独立地向 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 回答