【问题标题】:vb.net threading.thread addressof passing variablesvb.net threading.thread 传递变量的地址
【发布时间】:2012-04-16 20:06:32
【问题描述】:

我正在尝试将共享子中的 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 = ("Static: " & data)

错误 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()”兼容的签名。

【问题讨论】:

  • 你解决了我的“第三步”和“第四步”吗?对于傻笑,输入 Server,Public Shared refToMyForm as MyFormClass(其中MyFormClass 是表单的类名),然后将AddressOf getStatus 更改为AddressOf refToMyForm.getStatus

标签: vb.net parameter-passing addressof


【解决方案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?或者只是对表单的一些共享引用?

第四步是对 StringMessageReceived 的重新设计,使AddressOf 部分现在采用AddressOf refToMyForm.getStatus 的形式。

【讨论】:

    【解决方案2】:

    您需要使用委托 您的案例示例:

    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"})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-20
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      相关资源
      最近更新 更多