vb.net threading.thread addressof passing variables

落爺英雄遲暮 提交于 2019-12-13 04:05:29

问题


I am trying to pass some status from a IP call in a shared sub to a label on my form.

This is the current code that i am using:

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

The error its giving me is on the line lblStatus.text = ("Static: " & data)

Error 1 Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class.

Any help would be great!

David

UPDATE

After adding:

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

I get this error no one line Dim a As New Threading.Thread(AddressOf getStatus)

Error 1 Overload resolution failed because no accessible 'New' can be called with these arguments: 'Public Sub New(start As System.Threading.ParameterizedThreadStart)': Reference to a non-shared member requires an object reference. 'Public Sub New(start As System.Threading.ThreadStart)': Method 'Private Sub getStatus(data As Object)' does not have a signature compatible with delegate 'Delegate Sub ThreadStart()'.


回答1:


I've noticed you're trying to make this work using Shared members. That may be problematic for the following reasons:

(1) Without the Shared, behind the scenes a reference variable is created, and it is called Me. Via Me you can get to lblStatus, such as Me.lblStatus, and actually one doesn't necessarily need to put in the Me, one could specify lblStatus by itself. But, even by itself, the Me is implied there, and is still used.

(2) With the Shared, there is no Me. Without the Me, there is no lblStatus instance for the compiler to identify - hence the error. You will need to find some way to pass in a reference to your Form from which to access lblStatus. I need to warn you, though, that updating a Label or other user interface class directly from a thread other than the main thread is regarded as something bad - this is because WinForms is not thread-safe. Beginning with .NET Framework 2, you'll get an error if you try (although it is possible to opt-out of this error, at your own peril).

These are for C#, but it may give you some ideas on how to proceed:

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

So step one is to make getStatus not a shared member - that will bring back the Me.

Step two is to redesign getStatus into a thread-safe form for getting the text into the Label, such as:

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

Step three is to find some way to get a reference to your Form into Server - may be via a shared ArrayList? Or just some shared reference to Form?

Step four is a redesign of StringMessageReceived so that the AddressOf portion is now in the form of AddressOf refToMyForm.getStatus.




回答2:


You need to use Delegate Example for your case:

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

Then from your other thread you need to invoke:

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


来源:https://stackoverflow.com/questions/10180898/vb-net-threading-thread-addressof-passing-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!