Hello,

On my login form I have a timer and every tick I run this piece of code:

        Try

            Client.Connect(IpAddress, Port)

        Catch ex As SocketException

        End Try

and update a label to whether the server is online or offline. However when the server if offline it throws a exception error which makes the form unresponsive for a small amount of time. So my question is, is there a way to stop this?

Any help with this would be much appreciated,

Minko

Dani AI

Generated

was right: the UI freezes because Connect is a blocking call that waits for the OS timeout when the server is down. ’s move to run the check on another thread was the correct direction, but a couple of common pitfalls make the label appear not to update. The usual culprits are (a) updating a different form instance than the one shown (VB default-form instances can be deceptive), (b) using Invoke in a way that can deadlock, or (c) starting lots of overlapping threads/tasks so updates race or get lost.

Verify which instance is being updated and which thread runs the UI update: log Object.ReferenceEquals(Me, frmLogin) or write the thread id with Thread.CurrentThread.ManagedThreadId before and after marshaling. Prefer asynchronous connect patterns instead of raw threads and prefer BeginInvoke/Control.BeginInvoke or an async/await pattern to marshal UI updates (BeginInvoke schedules the update without blocking the caller).

A concise, modern pattern (no blocking on the UI thread, explicit timeout) is to use TcpClient.ConnectAsync with Task.WhenAny and then update the label via BeginInvoke. Example (VB.NET):

Private Async Function PingServerAsync(ip As String, port As Integer, timeoutMs As Integer) As Task(Of Boolean)
    Dim tcp As New System.Net.Sockets.TcpClient()
    Dim connectTask = tcp.ConnectAsync(ip, port)
    Dim finished = Await Task.WhenAny(connectTask, Task.Delay(timeoutMs))
    If finished Is connectTask Then
        Return True
    Else
        Try : tcp.Close() : Catch : End Try
        Return False
    End If
End Function

Call that from an async loop (single background monitor, not a new thread each timer tick) and marshal the label update safely:

' inside the form
Dim online = Await PingServerAsync(ip, port, 2000)
If lblServerStatus.InvokeRequired Then
    lblServerStatus.BeginInvoke(Sub() lblServerStatus.Text = If(online, "Server Status: Online", "Server Status: Offline"))
Else
    lblServerStatus.Text = If(online, "Server Status: Online", "Server Status: Offline")
End If

Additional notes: do not swallow exceptions silently (log them), avoid creating a new thread on every timer tick, and stop the monitor cleanly when the form closes. These steps address the UI freeze and the “label not changing” behavior seen in this thread.

Recommended Answers

All 4 Replies

When you try to connect, the connection does not happen instantaneously. The connection timeout has to elapse before the attempt fails. The way to avoid the freezing is to put the code in a separate thread. However, with that approach you have to use a delegate to update your main form from the thread. Fortunately, that is not difficult and I have an example of how to do that here.

I thought I was going to need to run it in a new thread, just wanted to make sure it was the correct thing to do.
Thank you very much for the help it is much appreciated.

Minko

If you have any problems getting the code to work feel free to continue this thread.

Hello,

I have set it up on another thread but I am having a problem. The problem is it still does not change the text. My code is as follows:

        Dim ServerStatusThread As New Thread(New ThreadStart(AddressOf ServerStatus))
        ServerStatusThread.Start()

            Private Delegate Sub dlgUpdateServerStatus(ByVal status As String)

    Public Sub ServerStatus()

        Do While frmLoginVisible
            If ConnectToServer() Then
                UpdateServerStatus("Online")
            Else
                UpdateServerStatus("Offline")
            End If
            System.Threading.Thread.Sleep(5000)
        Loop

    End Sub

    Private Sub UpdateServerStatus(ByVal status As String)

        If frmLogin.lblServerStatus.InvokeRequired Then
            Dim dlg As New dlgUpdateServerStatus(AddressOf UpdateServerStatus)
            frmLogin.Invoke(dlg, status)
        Else
            frmLogin.lblServerStatus.Text = "Server Status: " & status
        End If

    End Sub

It always runs this line of code:

frmLogin.lblServerStatus.Text = "Server Status: " & status

but the labels text never changes.

Hopefully you can help me figure this out. Thanks for the help so far,

Minko

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.