我正在尝试将某个状态从共享子中的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()'兼容的签名。
答案 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"})