Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple BackgroundWorker is not updating label on web page

I have used a piece of simple code from this helpful post

It uses a button and a label, the label should report "10% completed"... "20% completed"... and so on.

When I debug, the code is getting hit, but my label is not updating on the browser.

I have tried with & without update panels, with and without a masterpage.

protected void btnStartThread_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();

        // this allows our worker to report progress during work
        bw.WorkerReportsProgress = true;

        // what to do in the background thread
        bw.DoWork += new DoWorkEventHandler(delegate(object o, DoWorkEventArgs args)
        {
            BackgroundWorker b = o as BackgroundWorker;

            // do some simple processing for 10 seconds
            for (int i = 1; i <= 10; i++)
            {
                // report the progress in percent
                b.ReportProgress(i * 10);
                Thread.Sleep(1000);
            }
        });



        // what to do when progress changed (update the progress bar for example)
        bw.ProgressChanged += new ProgressChangedEventHandler(delegate(object o, ProgressChangedEventArgs args)
        {
            label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
        });


        // what to do when worker completes its task (notify the user)
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        delegate(object o, RunWorkerCompletedEventArgs args)
        {
            label1.Text = "Finished!";
        });

        bw.RunWorkerAsync();
like image 275
wotney Avatar asked Apr 29 '14 12:04

wotney


2 Answers

You could potentially do long polling to get your updated result. Personally I wouldnt use a background worker in a Web application. Also, consider looking at SignalR, Server Sent Events and Async and Await or the Task Parallel Library.

like image 135
brumScouse Avatar answered Oct 19 '22 22:10

brumScouse


BackgroundWorker is not suitable for ASP.NET and doesn't work with ASP.NET very well because ASP.NET works on a request/response model. To receive any updates the client's browser needs to request the information from the server. For example for your Label to be updated you will need to send a request for its new value to the server.

One option could be using AJAX for this purpose on the client to update the page. But rather than use formal AJAX, You can using an iframe that is a great way to asynchronously execute the long running process, without being dependent on any particular AJAX framework. When the button is clicked, an invisible iframe is dynamically generated and used to execute LongRunningProcess.aspx in the background:

<head runat="server">
<script type="text/javascript">
    function BeginProcess() {
        var iframe = document.createElement("iframe");
        iframe.src = "LongRunningProcess.aspx";
        iframe.style.display = "none";
        document.body.appendChild(iframe);
        document.getElementById('trigger').disabled = true;
    }

    function UpdateProgress(PercentComplete, Message) {
        document.getElementById('<%= Label1.ClientID %>').innerHTML = PercentComplete + '% ' + Message;
}
</script>
</head>

<body>
   <form id="form1" runat="server">
   <div>
    <input type="submit" value="Start Long Running Process" id="trigger" 
       onclick="BeginProcess(); return false;" style="width: 185px;"/>
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
   </div>
   </form>
</body>

And LongRunningProcess.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
   for (int i = 1; i <= 9; i++)
   {
       UpdateProgress(i * 10, " Completed.");
       System.Threading.Thread.Sleep(1000);
   }
   UpdateProgress(100, "Finished!");
}

protected void UpdateProgress(int PercentComplete, string Message)
{
    Response.Write(String.Format("<script type=\"text/javascript\">parent.UpdateProgress({0}, '{1}');</script>", PercentComplete, Message));
    Response.Flush();
}

You can see the result and also read more in Dave Ward's great article here: Easy incremental status updates for long requests.

like image 34
Salah Akbari Avatar answered Oct 20 '22 00:10

Salah Akbari