2012-04-16 33 views
0

我試圖通過一個共享sub中的IP調用將某些狀態傳遞給我的表單上的標籤。vb.net threading.thread傳遞變量的地址

這是當前的代碼,我使用:

Class Server 
    <STAThread()> Public Shared Sub Main() 
     Dim aTcpMessaging As IMessagingSystemFactory = New TcpMessagingSystemFactory() 
     Dim anInputChannel As IInputChannel = aTcpMessaging.CreateInputChannel(theIPforLocal & ":" & thePort) 
     Dim aStringMessagesFactory As IStringMessagesFactory = New StringMessagesFactory() 
     Dim aStringMessageReceiver As IStringMessageReceiver = aStringMessagesFactory.CreateStringMessageReceiver() 
     AddHandler aStringMessageReceiver.MessageReceived, AddressOf StringMessageReceived 

     aStringMessageReceiver.AttachInputChannel(anInputChannel) 
    End Sub 

    Private Shared Sub StringMessageReceived(ByVal sender As Object, ByVal e As StringMessageEventArgs) 
     LANResponse = Convert.ToString(e.Message) 
     Dim lanSent As String() = Nothing 
     Dim sep(3) As Char 
     Dim s As String = "" 

     sep(0) = "~" 
     'sep(1) = "," 
     lanSent = LANResponse.Split(sep, 2) 

     Dim a As New Threading.Thread(AddressOf getStatus) 

     a.SetApartmentState(Threading.ApartmentState.STA) 
     a.Start(Trim(lanSent(0)) & Trim(lanSent(1))) 
    End Sub 
End Class 

Private Shared Sub getStatus(ByVal data As Object) 
    lblStatus.text = ("Static: " & data) 
End Sub 

其給我的錯誤是上線lblStatus.text =( 「靜態」 &數據)

錯誤1無法從共享方法或共享成員初始值設定項中引用類的實例成員,而沒有該類的顯式實例。

任何幫助將是偉大的!

大衛

UPDATE

加入後:

Private Sub getStatus(ByVal data As Object) 
    If InvokeRequired Then 
     Invoke(New Action(Of Object)(AddressOf getStatus), data) 
    Else 
     lblStatus.Text = ("Static: " & data) 
    End If 
End Sub 

我得到這個錯誤誰都行暗淡了作爲新Threading.Thread(AddressOf的getStatus)

錯誤1 Overloader廣告解決失敗,因爲不能使用這些參數調用可訪問的'New': 'Public Sub New(start As System.Threading.ParameterizedThreadStart)':對非共享成員的引用需要對象引用。'Public Sub New(start As System.Threading.ThreadStart)':方法'Private Sub getStatus(data As Object)'沒有與委託'Delegate Sub ThreadStart()'兼容的簽名。

+0

你解決我的「第三步」和「第四步「?對於咯咯笑聲,把服務器,'公共共享refToMyForm作爲MyFormClass'(其中'MyFormClass'是你的表單的類名),然後改變'AddressOf getStatus'到'AddressOf refToMyForm.getStatus'。 – rskar 2012-04-17 13:31:39

回答

1

我注意到你正試圖使用​​Shared成員來完成這項工作。由於以下原因,這可能是有問題的:

(1)如果沒有Shared,幕後會創建一個參考變量,它被稱爲Me。通過Me您可以得到lblStatus,如Me.lblStatus,實際上並不一定需要輸入Me,您可以自行指定lblStatus。但是,即使其本身,暗示在那裏Me,並仍在使用。

(2)對於Shared,沒有Me。如果沒有Me,那麼編譯器沒有lblStatus實例來識別 - 因此是錯誤。 您將需要找到某種方式來傳遞您的表單的參考,從中訪問lblStatus。但是,我需要警告您,直接從主線程以外的線程更新Label或其他用戶界面類會被認爲是不好的 - 這是因爲WinForms不是線程安全的。從.NET Framework 2開始,如果您嘗試(如果您嘗試退出此錯誤,您可能會遇到自己的危險),但會得到一個錯誤。

這些是C#,但它可能給你如何進行的一些想法:

How to update the GUI from another thread in C#?

http://www.codeproject.com/Articles/23517/How-to-Properly-Handle-Cross-thread-Events-and-Upd

所以步驟之一就是讓的getStatus不是共享成員 - 這將帶來返回Me

第二步是重新設計的getStatus成線程安全的形式獲取文本標籤,如:

Private Sub getStatus(ByVal data As Object) 
    If InvokeRequired Then 
     Invoke(New Action(Of Object)(AddressOf getStatus), data) 
    Else 
     lblStatus.Text = ("Static: " & data) 
    End If 
End Sub 

第三步是要找到一些方式來獲得一個參考表單劃分爲Server - 可能是通過共享的ArrayList?或者只是一些對Form的共享引用?

第四步是StringMessageReceived的重新設計,因此AddressOf部分現在是AddressOf refToMyForm.getStatus的形式。

0

您需要使用委派 例如,對於你的情況:

Public Delegate Sub AddLabelTextDelegate(ByVal label As LabelControl, ByVal value As String) 

Public Sub AddLabelText(ByVal label As LabelControl, ByVal value As String) 
    label.Text = value 
End Sub 

然後將其他的線程需要調用:

 Me.lblStatus.Invoke(New AddLabelTextDelegate(AddressOf AddLabelText), New Object(){lblStatus, "Value"})