Search code examples
c#vb.netbackgroundworker

Running class as new thread


I want to start a job in a new thread or using backgroundworker to do it but havent done that before and asking you wich way I should do it.

My program has a datagridview with a list of files, one file per row. I want the user to be able to select a row and then press "Start download" to start a background job of the download. I want to get events back of the progress of the download.

I have a class clsDownload that handles everything and raises events back but how do I implement the backgroundworking?

Should I use the System.ComponentModel.BackgroundWorker inside of the class or create some wrapper that handles this or use some other threading stuff?

Thanks.

Edit: I dont understand how to implement my download in the backgroundworker, any small example would be very nice. The example on msdn didnt get me far.

I have a download class that has a StartDownload-function. Should I use the backgroundworker IN the class or in the caller? "feeling stupid"


Solution

  • I've created several different classes that incorporate BackgroundWorker. What I generally do is have a BackgroundWorker component on the form that will be open when the job is being performed, then I pass that instance to the constructor of my job class.

    Here is what your job class might look like:

    Private m_bwMain As BackgroundWorker
    
    Public Sub New(ByVal bwMain As BackgroundWorker)
        m_bwMain = bwMain
    
        'additional setup code here
    End Sub
    

    To start a job, you would do something like this in the Click event handler of your Start Download button:

    lblStatus.Text = "Initializing ..."
    bgwMain.RunWorkerAsync(someFileName)
    

    I declare my job class as a private member of the current form, then instantiate it in the BackgroundWorker.DoWork event. From there you can call your method to download a file:

    Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
        m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
        m_oJobEngine.DownloadFile(CStr(e.Argument))
    End Sub
    

    To report progress to the user, you can handle the events raised by your class in your main form. You just need to make sure the job class object declaration has the WithEvents keyword. From those handlers you can call the ReportProgress method of BackgroundWorker. From within ReportProgress you can make whatever changes you need to the UI to indicate progress. Here's an example:

    Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
        bgw.ReportProgress(0, bytesTransferred)
    End Sub
    Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
        lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
    End Sub
    

    Hope this helps.