Question

I'm trying to use a background worker to show a task is running and report back to the user the current progress. Having never used a backgroundworker before I did the usual googling and trying out of simple examples. This is where I'm currently getting stuck. I'm using this example on MSDN: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

However, I'm trying to do this using webforms. So I've set the Async property for the page to true. The problem is that it never updates my label during the process. It just updates it at the end. Here is the code:

I create a global backgroundworker:

    private BackgroundWorker bw = new BackgroundWorker();

In my Page_Load method I have:

    bw.WorkerReportsProgress = true;
    bw.WorkerSupportsCancellation = false;
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

Then the various methods:

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (!bw.IsBusy) bw.RunWorkerAsync();
    }


    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        for (int i = 1; i <= 10; i++)
        {
            System.Threading.Thread.Sleep(1000);
            worker.ReportProgress(i * 10);            
        }

    }

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        lblProgress.Text = "Processing... " + e.ProgressPercentage.ToString() + "%";
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null) lblProgress.Text = "Error Updating: " + e.Error.Message;
    }

However, it never updates during the process. I just see Processing...100% after 10 seconds. Help??

UPDATE

Ultimately I was able to spawn a new thread as per this example on MSDN: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.90).aspx

In case the link goes, here's the full example code:

using System;
using System.Threading;

public class Worker
{
    // This method will be called when the thread is started. 
    public void DoWork()
    {
        while (!_shouldStop)
        {
            Console.WriteLine("worker thread: working...");
        }
        Console.WriteLine("worker thread: terminating gracefully.");
    }
    public void RequestStop()
    {
        _shouldStop = true;
    }
    // Volatile is used as hint to the compiler that this data 
    // member will be accessed by multiple threads. 
    private volatile bool _shouldStop;
}

public class WorkerThreadExample
{
    static void Main()
    {
        // Create the thread object. This does not start the thread.
        Worker workerObject = new Worker();
        Thread workerThread = new Thread(workerObject.DoWork);

        // Start the worker thread.
        workerThread.Start();
        Console.WriteLine("main thread: Starting worker thread...");

        // Loop until worker thread activates. 
        while (!workerThread.IsAlive);

        // Put the main thread to sleep for 1 millisecond to 
        // allow the worker thread to do some work:
        Thread.Sleep(1);

        // Request that the worker thread stop itself:
        workerObject.RequestStop();

        // Use the Join method to block the current thread  
        // until the object's thread terminates.
        workerThread.Join();
        Console.WriteLine("main thread: Worker thread has terminated.");
    }
}
Was it helpful?

Solution

You cannot report progress back from an ASP.NET page this way.

You need some transport mechanism to do this. Some options:

  1. Use AJAX to poll the progress each X seconds;
  2. Use Web Sockets to report progress back to the client.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top