vb.net threading.thread传递变量的地址

时间:2012-04-16 20:06:32

标签: vb.net parameter-passing addressof

我正在尝试将某个状态从共享子中的IP调用传递到表单上的标签。

这是我正在使用的当前代码:

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 =(“静态:”&amp;数据)

  

错误1如果没有类的显式实例,则无法在共享方法或共享成员初始值设定项中引用类的实例成员。

任何帮助都会很棒!

大卫

更新

添加后:

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

我收到此错误没有一行 Dim a As New Threading.Thread(AddressOf getStatus)

  

错误1重载解析失败,因为无法使用以下参数调用可访问的“新建”:       '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()'兼容的签名。

2 个答案:

答案 0 :(得分: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重新设计为线程安全的形式,以便将文本放入Label中,例如:

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的形式。

答案 1 :(得分: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"})