2012-06-08 46 views
1

一個線程內引用的對象(類)失敗一個線程內引用的對象(類)失敗

我有一個對象(「一個VB類」),需要在單獨的線程運行,並進行通信與U/I。

即使使用示例代碼,我也無法讓對象在線程中運行。我用兩個例子來演示這個問題。第一個在窗體中調用一個函數,它完美地工作。第二個創建一個對象並執行相同的調用,但失敗。


示例#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內的線程樣本完成
Inside new thread ....
oFuctionToBeRunInThread

這是我的預期。線程異步啓動。結束很快,並且該函數知道它在一個線程中。




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


這裏是包含類定義的外部文件:

 
    Public Class objTest 

    Private Delegate Sub oFuctionToBeRunInThreadDelegate() 

    Public Sub oFuctionToBeRunInThread() 

     If frmInitial.InvokeRequired Then 
      Console.WriteLine("Inside new thread....") 
      frmInitial.Invoke(New oFuctionToBeRunInThreadDelegate(AddressOf oFuctionToBeRunInThread)) 
     Else 
      Console.WriteLine("oFuctionToBeRunInThread") 
     End If 

    End Sub 
    End Class 

在這種情況下,輸出是證明該函數不在單獨運行線。 如下所示:

使用對象的線程樣本已啓動。
使用對象完成的線程示例。
oFuctionToBeRunInThread



摘要:當線程創建對象,看來該對象實際上並非一個線程中運行,否則form.InvokeRequired將是真實的。我還有其他更復雜的例子,在這方面得到了強有力的證實和證明,但我提供了這兩個例子,作爲我的問題的一個非常簡單的示範。

如何讓一個線程「擁有」一系列單獨的對象,以便這些對象異步運行並可以獨立地向U/I報告?

+0

[Ther e是VB.Net中的窗體的默認實例,但不是在C#中,爲什麼?](http://stackoverflow.com/questions/4698538/there-is-a-default-instance-of-form-in-vb-網絡但不在 - 爲什麼) –

+0

你是鏈接問題答案最後一段的另一個受害者。 –

+0

漢斯,它可能是重複的......也許是爲了更明智的眼睛或理解。我無法看到它們是如何相同的。儘管感謝您的鏈接。 – NameIsPete

回答

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 

screen snapshot

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 

相信我的路比我的數字學習更好分析考試:-)

+0

這是真的。當函數是「Me.InvokeRequired」形式的成員時,返回True。但是,在函數是類的成員的情況下,「frmInitial.InvokeRequired」返回false。 任何想法,爲什麼這是?我真的很難過。 感謝您花時間瀏覽本頁。 – NameIsPete

+0

太棒了!謝謝!我明天會試試這個。這很有道理。 – NameIsPete

+0

**謝謝** - 這可行。我仍然對整體線程感到困惑,但我相信我可以將其融入到項目中。非常感謝你! – NameIsPete

相關問題