Using Asp.Net BackgroundWorker To Create Progress Bar

BackgroundWorker is a component that runs asynchronously as in the background. We need to create and use it along with Ajax to occupy async process.

In the previous post, I already have an example of create a BackgroundWorker example using client script, ASP .Net Ajax BackgroundWorker Example Using Client Script & PageMethods.

In this post, I use System.ComponentModel.BackgroundWorker class to run a background process. Its progress status will be showed in progress bar.
That progress bar is located inside ModalPopupExtender Ajax Control Toolkit. So when backgroundWorker is running no UI activity allowed exept that inside the ModalPopupExtender.

This example only do simple calculation. After calculation is completed the result shows on result div element. Its progress percentage showed as a progress bar.


Here’s the block source code example, .aspx file:



    
     


 
    <div>
        
        
        
        
            var stopped = false;
            function BeginRequestHandler(sender, args) {
                stopped = false;
                $get('').innerHTML = '0%';
                $get('progbar').style.width = '0%';
                $get('btnstop').disabled = '';
                PageMethods.RunAsync($get('').value, RunAsyncSuccess);
                setTimeout("ProgressChanged()", 10);
            }

            function RunAsyncSuccess() {
                if (!stopped) {
                    $get('').disabled = '';
                    $get('').click();
                   
                }
                stopped = false; 
            }

            function ProgressChanged() {
                PageMethods.Progress(Progress_success_callback);
            
            }

            function Progress_success_callback(response) {
                $get('').innerHTML = response + '%';
                $get('progbar').style.width = response + '%';
                setTimeout("ProgressChanged()", 10);
            }

            function CancelAsync() {
                stopped = true;
                $get('').disabled = '';
                PageMethods.CancelAsync();
                $get("result").innerHTML = "Cancelled";
            }

            function _ok() {
                PageMethods.FinalResult(FinalResult_succcess_callback);
            }

            function FinalResult_succcess_callback(response) {
                if (!stopped) {
                    $get("result").innerHTML = response;
                }
            }
        
    
   <table>
        <tr valign="top">
        <td>
        Number To Compute:  <br />
       
        
       
        
              Progress: <br />
              <div id="progbar_panel" style="width:150px;height:20px;border:solid thin;">
              <div id="progbar" style="background-color:Blue;width:0;height:100%;"></div>
              </div>
              <br />
              &nbsp;             
             
        
       
        </td>
            
        </tr>
        <tr><td>Calculation result: <div id="result"></div></td></tr>
    </table>
       
    </div>
    
	

I use two div elements to represent progress bar. There are outer div (ID progbar_panel) and inner div (ID progbar). Initialy inner div has width 0% relative to outer and its background color is blue.

With javascript I update the inner div’s width along with progress percentage that returned from server side script. PageMethods is used to call server side script from client script.

If the calculation is complete then ModalPopup automatically closed and calculation’s result is showed in result div element. But If it is cancelled then ‘Cancelled’ will appear.

Code behind file:

Imports System.ComponentModel
Imports System.Threading
Imports System.Web.Services
Partial Class BgWork
    Inherits System.Web.UI.Page
    Public Shared bgwork As BackgroundWorker
    Public Shared percentage As Integer = 0
    Public Shared numberToCompute As Integer
    Public Shared highestPercentageReached As Integer = 0
    Public Shared calcresult As Integer

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load


    End Sub

    Private Shared Sub bgwork_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        Dim result As Integer = 0
        For i As Integer = 1 To numberToCompute
            If bgwork.CancellationPending = True Then
                e.Cancel = True

            Else
                result = result + i
                Dim percentComplete As Integer = Convert.ToInt32(i * 100 / numberToCompute)

                Thread.Sleep(700)
                bgwork.ReportProgress(percentComplete)
            End If

        Next
        e.Result = result
    End Sub

    
    Private Shared Sub bgwork_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        calcresult = e.Result
    End Sub

     _
    Public Shared Function FinalResult() As Integer
        Return calcresult

    End Function

     _
    Public Shared Function Progress() As Integer
        Return percentage

    End Function

     _
    Public Shared Sub CancelAsync()
        bgwork.CancelAsync()

    End Sub

     _
    Public Shared Sub RunAsync(ByVal txmax As Integer)
        numberToCompute = txmax
        calcresult = 0
        percentage = 0
        bgwork = New BackgroundWorker()
        bgwork.WorkerReportsProgress = True
        bgwork.WorkerSupportsCancellation = True

        AddHandler bgwork.DoWork, AddressOf bgwork_DoWork
        AddHandler bgwork.RunWorkerCompleted, AddressOf bgwork_Completed
        AddHandler bgwork.ProgressChanged, AddressOf bgwork_ProgressChanged

        bgwork.RunWorkerAsync()
    End Sub

    Private Shared Sub bgwork_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        percentage = e.ProgressPercentage
    End Sub
End Class

BackgroundWorker component (ID bgwork) has events such as DoWork, ProgressChanged and RunWorkerCompleted.
I add those event with AddHandler method because of this BackgroundWorker component is created on the fly.
Note: All BackgroundWorker method using ‘Shared’ modifier so that I can access the same instance of it.

Also I have Attribute on several functions so those functions can be accessed using client script.

Regards,
Agung Gugiaji

Advertisements

4 responses to “Using Asp.Net BackgroundWorker To Create Progress Bar

  1. Hi Agung, is there some reason why your code might not word if I create a session variable? Your solution is good. I tried it and it works perfectly for me. But then when I create the first session variable, the background loop no longer can update the progress. It is very strange. How could session variables affect Javascript screen updates? I don’t get it. Thanks in advance.

    • Hi Joe,

      When you want to call server side function and/or retrieve server variable value using PageMethod then you should consider to use ‘Shared’ (Vb.net) or ‘static’ (C#) keyword to ensure you access same instance of that function/variable.

      If you use session then PageMethod might access different instance of session even if you have same session name in the code.

      Thanks for your attention to my post

  2. Hi Agung,
    Great idea.
    I tryed to quick use this using standard MS ajax, and it works like a charm (without the ModalPopup, but enough for me)
    I had to change the “btncompute” button to make it not submit the form, dunno if this is a side effect of not using ajaxToolkit.
    anyway, thx for sharing.
    Gislain.

  3. Hello,
    A very great post!
    However, I have a strange problem. my progressSuccess don’t execute it, since runAsyncSuccess has finished. Seems that when I call to PageMethods.Progress(progressSuccess), progressSuccess is not called since the function runAsyncSuccess has been terminated.
    Some advice?

    ¡Sorry for my bad english!

    Best regards,

    Juanjo.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s