Results 1 to 10 of 10

Thread: BackroundWorker Problem that I can't figure out

Threaded View

  1. #5
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: BackroundWorker Problem that I can't figure out

    Quote Originally Posted by .paul. View Post
    here's an example:

    Code:
    Public Class Form1
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            BackgroundWorker1.RunWorkerAsync()
        End Sub
    
        Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            For x As Integer = 1 To 10
                setText(x.ToString)
                MsgBox(getText)
            Next
        End Sub
    
        Private Delegate Sub setTextCallBack(ByVal newValue As String)
        Private Sub setText(ByVal newValue As String)
            If TextBox1.InvokeRequired Then
                TextBox1.Invoke(New setTextCallBack(AddressOf setText), newValue)
            Else
                TextBox1.Text = newValue
            End If
        End Sub
    
        Private Delegate Function getTextCallBack() As String
        Private Function getText() As String
            If TextBox1.InvokeRequired Then
                Return DirectCast(TextBox1.Invoke(New getTextCallBack(AddressOf getText)), String)
            Else
                Return TextBox1.Text
            End If
        End Function
    
    End Class
    While this would work, this seems to defeat the whole purpose of the BackgroundWorker class. The background worker class was really meant to avoid this type of code. It has all the logic already built into it.
    Whenever you want to access any UI element, do that via the ReportProgress method and ProgressChanged event. You can pass the ProgressPercentage to the ProgressReport method, telling it how much of your work is complete. Additionally you can pass it the UserState parameter with whatever value you want and do UI related things with that, if required. These two things are available for use in the ProgressChanged event handler.

    Here is an example of how to do it the proper way, avoiding delegates:
    Put a TextBox, a ProgressBar, and two Buttons on a form and the following code.
    vb.net Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.     ProgressBar1.Maximum = 100
    3.     ProgressBar1.Value = 0
    4.     BackgroundWorker1.WorkerReportsProgress = True
    5.     BackgroundWorker1.WorkerSupportsCancellation = True
    6.     BackgroundWorker1.RunWorkerAsync()
    7. End Sub
    8.  
    9. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    10.     ' Cancel button
    11.     BackgroundWorker1.CancelAsync()
    12. End Sub
    13.  
    14. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    15.     Const MAX As Integer = 1000
    16.     For i As Integer = 1 To MAX
    17.         ' some delay to simulate work in progress
    18.         Threading.Thread.Sleep(100)
    19.  
    20.         ' report the progress to UI. You can optionally pass any values required to be accessed by UI elements.
    21.         Dim progress As Integer = (i * 100) \ MAX
    22.         BackgroundWorker1.ReportProgress(progress, i)
    23.         ' check if user wants to cancel this task. If Yes, then quit.
    24.         If BackgroundWorker1.CancellationPending Then
    25.             e.Cancel = True
    26.             Exit Sub
    27.         End If
    28.     Next
    29. End Sub
    30.  
    31. Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    32.     ProgressBar1.Value = e.ProgressPercentage
    33.     TextBox1.Text = e.UserState.ToString
    34. End Sub
    35.  
    36. Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    37.     If e.Cancelled Then
    38.         MessageBox.Show("Cancelled!")
    39.     Else
    40.         MessageBox.Show("Work done")
    41.     End If
    42. End Sub
    Run the program and first click Button1. It will start the background worker thread. Click Button2 anywhere in between to cancel it.
    Last edited by Pradeep1210; Oct 25th, 2013 at 09:24 AM. Reason: Corrected grammar and explained in detail.
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width