0

我正在尝试将共享子中的 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

我收到此错误 no one line Dim a As New Threading.Thread(AddressOf getStatus)

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

4

2 回答 2

1

我注意到您正在尝试使用Shared成员来完成这项工作。这可能是有问题的,原因如下:

(1) 没有Shared,在幕后会创建一个引用变量,并调用它MeMe可以通过,lblStatus比如Me.lblStatus,其实不一定需要放入Me,可以lblStatus自己指定。但是,即使它本身Me也隐含在其中,并且仍在使用。

(2) 有Shared,没有Me。如果没有Me,则lblStatus编译器无法识别实例 - 因此会出现错误。您将需要找到某种方法来传递对您的 Form 的引用,以便从中访问lblStatus。不过,我需要警告您,直接从主线程以外的线程更新标签或其他用户界面类被认为是不好的 - 这是因为 WinForms 不是线程安全的。从 .NET Framework 2 开始,如果您尝试,您会收到一个错误(尽管您可以选择退出此错误,但后果自负)。

这些是针对 C# 的,但它可能会给你一些关于如何继续的想法:

如何从 C# 中的另一个线程更新 GUI?

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.

于 2012-04-16T21:16:15.260 回答
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"})
于 2013-05-17T18:06:04.373 回答