0

I have the following code:

Public Class Form1
Dim ping As New Ping
Dim replyeuw As PingReply
Dim euwthread As Thread
Dim num As Integer = 0
Dim pingms As Integer

Public Sub pingareuw()
    If My.Computer.Network.IsAvailable Then
        replyeuw = ping.Send("prod.euw1.lol.riotgames.com")
        pingms = replyeuw.RoundtripTime
        If replyeuw.Status = IPStatus.Success Then
            FlatLabel3.Text = "EUW PING: " & pingms
        Else
            FlatLabel3.Text = "Nope..."
        End If
        Thread.Sleep(500)
    Else
        MsgBox("Liga a net pah!")
    End If
End Sub
Private Sub FormSkin1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    euwthread = New Thread(AddressOf Me.pingareuw)
    euwthread.Start()
End Sub

And I'm getting this error:

Cross-thread operation not valid: Control 'FlatLabel3' accessed from a thread other than the thread it was created on.

Why?

LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • 1
    possible duplicate of [Crossthread operation not valid... - VB.NET](http://stackoverflow.com/questions/2240702/crossthread-operation-not-valid-vb-net) – pmcoltrane Feb 20 '15 at 15:21
  • Because... you can't access a control from a thread other than the thread it was created on... and you're creating a thread and trying to access a control from it... pretty self-explanatory isn't? – Josh Part Feb 20 '15 at 15:23

2 Answers2

0

You cannot modify a Control from a Thread other than the thread which created it (which normally is the main thread of the application). Instead, you can use a BackgroundWorker.

Private bw As BackgroundWorker

Private Sub FormSkin1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' create a new Backgroundworker and start it
    bw = New BackgroundWorker
    bw.WorkerReportsProgress = True
    bw.RunWorkerAsync()
End Sub

Private Sub bg_DoWork(sender As Object, args As DoWorkEventArgs) _
                     Handles bg.DoWork

    If My.Computer.Network.IsAvailable Then
        replyeuw = ping.Send("prod.euw1.lol.riotgames.com")
        pingms = replyeuw.RoundtripTime
        If replyeuw.Status = IPStatus.Success Then
            bg.ReportProgress(0, "EUW PING: " & pingms)
        Else
            bg.ReportProgress(0, "Nope...")
        End If
        Thread.Sleep(500)
    Else
        MsgBox("Liga a net pah!")
    End If

End Sub

Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles bg.ProgressChanged 
    ' you can access the control here
    FlatLabel3.Text = e.ToString()
End Sub
WeSt
  • 2,628
  • 5
  • 22
  • 37
0

Normally your forms application is tagged as a "StaThread". This means "single threaded apartment", which is lingo from the good old COM days. Your Form and the controls on it live in the believe, that they will never be called from any other thread as the thread they were created in.

To overcome your problem, you need to use the function "InvokeRequired" from your forms class in your functions which are called from another thread.

The basic scheme to do that is (Sorry for nearly - c# syntax - same in VB):

void MaybeCalledFromOtherThread()
{
    if( this.InvokeRequired )
         return this.Invoke(MaybeCalledFromOtherThread) // not exact syntax for Invoke

    // code below only executed from the correct thread.
}

So, in your case you best add a member function to your Forms class, like UpdatePingDisplay(string newText) and use the trick shown above for that. From your thread, you then replace those direct operations on the label with a call to the new function and all should work.

BitTickler
  • 10,905
  • 5
  • 32
  • 53