Share
       















  How To ...
     
      Multi-Threading an application with DBI .NET Controls






dbiCalendarWPF - Golf Course Tee Time Scheduling Demo





Resources


Smart Client

Web Demos



Tech Tips


The Dynamics of
Scheduling white paper



Warehouse Shipment Scheduling o
n YouTube
 


.NET Products

Solutions Schedule


Studio Controls


Extractor



COM Products


Solutions Schedule


Studio Controls


Extractor



Frameworks


Warehouse and Shipment Scheduling




Commercial Software

Staff Scheduler Pro



    Free Trial

 

Hello All,

     For Today's Tech Tip, we thought we would branch out from just showcasing the great built in features of our controls and show off some .NET functionality that can be applied to numerous scenarios involving many different controls and applications.

Multi-Threading

The basic concept for multi-threading is to take the major processing away from the main application thread (to avoid the dreaded "Not Responding" message from windows), and also to be able to give proper feedback to users as tasks process and complete.

A nice and easy way to reflect the current status of an operation is with, everyone's favorite control, the Progress Bar. The Progress Bar is universally understood, well if you are used to using computers at least :), and a very simple way to display the needed information.  The issue that arises when trying to use it, is that trying to perform your processing and updating the Progress Bar, will max out the current thread and bring the application to its knees.  This is where Multi-Threading comes in, because you can move ALL of the processing operations to new threads, and leave the main thread to refresh the Progress Bar with the progress as each thread reports back.

 

We have have put together a small sample that shows using two threads for "processing" in addition to the main application thread.

This sample uses the following controls, on a single form:
2 dbiMeter controls (used as Progress Bars)
1 dbiDial control (used to modify the increment of 1 dbiMeter)
1 dbiSlide control (used to modify the increment of 1 dbiMeter)
4 standard button controls (used for starting and stopping the additional threads)
2 Background Worker controls (these controls will handle the additional threads).

 

Here is what the form looks like with all the controls:

And because they are non-visual controls, the 2 Background Workers will appear in the Designer Tray, below the form in the Visual Studio designer, like so:
Designer Tray with Background Worker controls.

Now for the code:

Here we initialize the form, and set the range of the dbiDial and dbiSlide controls.  In this example, these two controls can be used to change the value the dbiMeter controls will increment by (1-10). They are independent of each other and only affect 1 dbiMeter each.

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'Set up the dbiDial and dbiSlide controls with a few parameters.

        'These controls will be used to adjust the increments of the dbiMeter controls.
        Me.DbiDial1.Maximum = 10
        Me.DbiDial1.Minimum = 1
        Me.DbiDial1.Value = 1

        Me.DbiSlide1.Maximum = 10
        Me.DbiSlide1.Minimum = 1
        Me.DbiSlide1.Value = 1
        Me.DbiSlide1.ShowDivisions = 0
        Me.DbiSlide1.ShowMax = 10
        Me.DbiSlide1.ShowMin = 1

        Me.ButtonStop1.Enabled = False
        Me.ButtonStop2.Enabled = False

        'The background workers will be allowed to report their progress as well as be cancelled
        Me.BGW_DialMeter.WorkerReportsProgress = True
        Me.BGW_DialMeter.WorkerSupportsCancellation = True
        Me.BGW_SlideMeter.WorkerReportsProgress = True
        Me.BGW_SlideMeter.WorkerSupportsCancellation = True

    End Sub

And here is the code for the first group of controls (1 dbiMeter, 1 dbiDial, 2 standard buttons, and 1 of the Background Workers):

#Region "dbiMeter 1, Horizontal"

    Private Sub ButtonStart1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStart1.Click
        Me.ButtonStart1.Enabled = False
        Me.ButtonStop1.Enabled = True
        Me.BGW_DialMeter.RunWorkerAsync() 'Start the background worker to run its process
    End Sub

    Private Sub ButtonStop1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStop1.Click
        Me.BGW_DialMeter.CancelAsync() 'Tell the background worker to finish its processing
        Me.ButtonStop1.Enabled = False
        Me.ButtonStart1.Enabled = True
    End Sub

    Private Sub BGW_DialMeter_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW_DialMeter.DoWork
        'To simulate processing, we will use a Do While Loop, and issue a Sleep command

        'As long as the background worker hasn't been told to stop, the loop will continue
        Do While BGW_DialMeter.CancellationPending = False

            'Update the dbiMeter control's value, to represent the progress
            If Me.DbiMeter1.Value + Me.DbiDial1.Value <= 100 Then
                BGW_DialMeter.ReportProgress(Me.DbiMeter1.Value + Me.DbiDial1.Value)
            Else
                BGW_DialMeter.ReportProgress(0)
            End If

            System.Threading.Thread.Sleep(1000) 'Pause the thread for 1 second
        Loop
    End Sub

    Private Sub BGW_DialMeter_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW_DialMeter.ProgressChanged
        'The dbiMeter control is updated with the progress reported by the background worker
        Me.DbiMeter1.Value = e.ProgressPercentage
    End Sub

 #End Region

The other set of controls has an identical set of code:

#Region "dbiMeter 2, Vertical"
    Private Sub ButtonStart2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStart2.Click
        Me.ButtonStart2.Enabled = False
        Me.ButtonStop2.Enabled = True
        Me.BGW_SlideMeter.RunWorkerAsync() 'Start the background worker to run its process
    End Sub

    Private Sub ButtonStop2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonStop2.Click
        Me.BGW_SlideMeter.CancelAsync() 'Tell the background worker to finish its processing
        Me.ButtonStop2.Enabled = False
        Me.ButtonStart2.Enabled = True
    End Sub

    Private Sub BGW_SlideMeter_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW_SlideMeter.DoWork
        'To simulate processing, we will use a Do While Loop, and issue a Sleep command

        'As long as the background worker hasn't been told to stop, the loop will continue
        Do While BGW_SlideMeter.CancellationPending = False

            'Update the dbiMeter control's value, to represent the progress
            If Me.DbiMeter2.Value + Me.DbiSlide1.Value <= 100 Then
                BGW_SlideMeter.ReportProgress(Me.DbiMeter2.Value + Me.DbiSlide1.Value)
            Else
                BGW_SlideMeter.ReportProgress(0)
            End If

            System.Threading.Thread.Sleep(1000) 'Pause the thread for 1 second
        Loop
    End Sub

    Private Sub BGW_SlideMeter_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW_SlideMeter.ProgressChanged
        'The dbiMeter control is updated with the progress reported by the background worker
        Me.DbiMeter2.Value = e.ProgressPercentage
    End Sub
 #End Region

When each of the Start buttons is pressed, they give the command to their respective Background Worker to begin running asynchronously.  The Background Worker will then trigger its DoWork event.  It is from this event that all processing on the secondary thread processes (when the event finishes, the Background Workers thread will automatically stop). In the example posted, we simply used a Do While Loop and a Sleep command to simulate the event performing a process.  In reality, you can use these events to handle your data load, or an update process, or even a constant validation routine when working in a multi-user data environment.

To stop either of the Background Workers, simply press one of the stop buttons.  This will call the CancelAsync method on the respective worker thread, which will set it as CancellationPending = True, which will end the process inside the DoWork event (stopping the thread).

If you would like a closer look at the sample, in either a working example or the source code, please see the following links:

Run a Smart Client sample:
Download a compiled version of the sample:
Download the Visual Basic .NET Visual Studio 2008 source code:

Take care and have a nice day!

 

      Free Trial
     
       
      all rights reserved  |  copyright © 1996 - 2017   |  Terms of Use
 
      https://www.dbi-tech.com