Link to home
Start Free TrialLog in
Avatar of derek7467
derek7467

asked on

vb.net and background worker for system uptime

I am attempting to write a small amount of code to return to me the system uptime of a remote workstation.  It works when ran directly from a button, but when i try to put it in a background thread it fails everytime.

Below is the code i am using:

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Try
            Dim str_ServerName As String = TextBox1.Text
            Dim pc As New PerformanceCounter("System", "System Up Time", "", str_ServerName)
            pc.NextValue()
            Dim ts As TimeSpan = TimeSpan.FromSeconds(pc.NextValue)
            MsgBox(str_ServerName & " has been up for " & ts.Days & " days, " & ts.Hours & " hours, " & ts.Minutes & " minutes, " & " and " & ts.Seconds & " seconds.", , "System Uptime")
        Catch ex As Exception
            MsgBox("Workstation Uptime not found", MsgBoxStyle.Information, "Information")
        End Try
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        If e.Cancelled = True Then
        End If
    End Sub

Open in new window


I declare the below:
Private bw As BackgroundWorker = New BackgroundWorker
    Public Sub New()
        InitializeComponent()
        bw.WorkerReportsProgress = True
        bw.WorkerSupportsCancellation = True
        AddHandler bw.DoWork, AddressOf BackgroundWorker1_DoWork
        AddHandler bw.ProgressChanged, AddressOf BackgroundWorker1_ProgressChanged
        AddHandler bw.RunWorkerCompleted, AddressOf BackgroundWorker1_RunWorkerCompleted
    End Sub

Open in new window


I then try to run the method from a button:
  If Not bw.IsBusy = True Then
            bw.RunWorkerAsync()
        End If

Open in new window


What am i doing wrong?
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

The background worker doesn't support UI - eg. MessageBox - elements.  You would need to pass the uptime back to the main thread to display the result.
Avatar of derek7467
derek7467

ASKER

This is the error i get:

Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on.
How do i pass it back?
I supposed this would be bad coding to use the below???

TextBox.CheckForIllegalCrossThreadCalls = false
Use a BeginInvoke to bubble it up to the UI thread:
http://msdn.microsoft.com/en-us/library/a06c0dc2(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
Me.BeginInvoke(new Delegate(AddressOf showMsgBox),  str_ServerName & " has been up for " & ts.Days & " days, " & ts.Hours & " hours, " & ts.Minutes & " minutes, " & " and " & ts.Seconds & " seconds.", "System Uptime")

public sub showMessageBox(text as string, Caption as string)
 MsgBox(text, , Caption)
end sub

Open in new window

Hi, I suggest all will become clear when you Google "InvokeRequired"
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I agree with Mike:  The BW supports passing data back to the UI via its established events. There is no need for CheckForIllegalCrossThreadCalls, BeginInvoke, or InvokeRequired as the others have mentioned.
From the help files about the BackgroundWorker:
http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

To pass data back to the calling process, set the Result property of the DoWorkEventArgs object that is passed to the event handler. This value can be read when the RunWorkerCompleted event is raised at the end of the operation.
thank you
ps.
Reading the help files could result in a quicker answer than just asking a question and waiting.