Solved

asp.net BackGroundWorker RunWorkerCompleted

Posted on 2013-12-02
11
830 Views
Last Modified: 2014-02-19
I have an async process called from javascript using a PageMethod that executes a potentially long running process and updates a progress bar.  I'm trying to capture any errors/messages from the async process and report it to the user on a page control.  Tried sending a message from RunWorkerCompleted to the async success callback, but with no luck.

any help would be greatly appreciated.

Including relevant code.

thanks

// ** aspx code behind

Imports System.ComponentModel
Imports System.Threading
Imports System.Web.Services


    Protected Shared Sub ExportTaxesServices(ByVal sender As Object, ByVal e As DoWorkEventArgs)
        Dim dt As New DataTable

        ' Do the long running process
        Try
            args = CType(e.Argument, List(Of String))

            ' run the method to get rows for the datatable.   excluded for clarity
            For Each row As DataRow In dt.Rows

                    ' Calculate the percentage complete for this routine
                    percentComplete = Convert.ToInt32(i * 100 / rowCount)

                    ' Send the percentage complete to the async process that updates the rogress bar
                    bgWorker.ReportProgress(percentComplete)
                    i += 1
            Next
        Catch ex As Exception
            Throw ex
        End Try

    End Sub


    ' Return the percentage completed  
    <WebMethod()> _
    Public Shared Function Progress() As Integer
        Return percentage

    End Function

    ' Cancel the async call
    <WebMethod()> _
    Public Shared Sub CancelAsync()
        bgWorker.CancelAsync()

    End Sub

    ' Main routine that initiates the async call
    <WebMethod()> _
    Public Shared Sub RunAsync(ByVal taxType As String, ByVal invoiceDate As String, ByVal startDate As String, ByVal endDate As String, _
                               ByVal cycleID As String, ByVal userID As String)

        ' Add the list of parameters received from the javascript async call to a List
        Dim args As New List(Of String)
        args.Add(invoiceDate)
        args.Add(startDate)
        args.Add(endDate)
        args.Add(cycleID)
        args.Add(userID)

        percentage = 0

        ' Create the backgroundworker to execute the async calls on a separate thread
        bgWorker = New BackgroundWorker()
        bgWorker.WorkerReportsProgress = True
        bgWorker.WorkerSupportsCancellation = True

        Select Case taxType
            ' Set which routine will be run asynchronously
            Case "Services"
                AddHandler bgWorker.DoWork, AddressOf ExportTaxesServices

            Case "Usage"
                AddHandler bgWorker.DoWork, AddressOf ExportTaxesUsage

        End Select

        ' Set the routine that will be called when the progess of the async call changes
        AddHandler bgWorker.ProgressChanged, AddressOf bgWorker_ProgressChanged
        AddHandler bgWorker.RunWorkerCompleted, AddressOf bgWorker_Completed

        ' Start the async process, passing in the parameters
        Try
            bgWorker.RunWorkerAsync(args)
        Catch ex As Exception
            Throw ex
        End Try

    End Sub

    ' Gets the percentage completed of the async call
    Private Shared Sub bgWorker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        percentage = e.ProgressPercentage

    End Sub
    Private Shared Function bgWorker_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) As String
        Return "ok"

    End Function

// ** aspx javascript code

    <script type="text/javascript" language="javascript">

        var stopped = false;
        // Starts the async process with parameters if page passes validation
        if (Page_ClientValidate()) {
            function beginRequestHandler(sender, args) {
                stopped = false;
                var invoiceDate = new Date($get('<%= txtInvoiceDate.ClientID %>').value);
                invoiceDate = invoiceDate.getFullYear() + "-" + (invoiceDate.getMonth() + 1) + "-" + invoiceDate.getDate();

                var startDate = new Date($get('<%= txtStartDate.ClientID %>').value);
                startDate = startDate.getFullYear() + "-" + (startDate.getMonth() + 1) + "-" + startDate.getDate();

                var endDate = new Date($get('<%= txtEndDate.ClientID %>').value);
                endDate = endDate.getFullYear() + "-" + (endDate.getMonth() + 1) + "-" + endDate.getDate();

                var ddlCycleID = $get('<%= ddlBillingCycle.ClientID %>');
                var cycleID = ddlCycleID.options[ddlCycleID.selectedIndex].value;

                var ddlType = $get('<%= ddlType.ClientID %>');
                var taxType = ddlType.options[ddlType.selectedIndex].value;

                var userID = '<%= Session("UserID") %>';

                $get('<%= btnConfirm.ClientID %>').disabled = 'disabled';
                $get('<%= btnCancel.ClientID %>').disabled = 'disabled';
                $get('<%= progressPercent.ClientID %>').innerHTML = '0%';
                $get("<%= panelMessages.ClientID %>" + "_MessagePanel").style.display = 'none';
                $get('progressBar').style.width = '0%';
                PageMethods.RunAsync(taxType, invoiceDate, startDate, endDate, cycleID, userID, runAsyncSuccess, runAsyncFailure);
                setTimeout("progressChanged()", 10);
            }
        }

        // Closes the progress bar window and calls the function to refresh grid with results after the async call completes successfully.
        function runAsyncSuccess(result) {
            if (!stopped) {
                $find('modalProgressBehaviorID').hide();
                $get('<%= btnConfirm.ClientID %>').disabled = '';
                $get('<%= btnCancel.ClientID %>').disabled = '';
                $get('<%= btnCalculate.ClientID %>').disabled = 'disabled';
                refreshGrid('<%=hfRefereshGrid.ClientID %>');
                alert(result.get_message());
            }
            stopped = false;
        }

        function runAsyncFailure(result) {
            alert(result.get_message());
        }

        // Calls the Progress method to get the percent complete of the async process
        function progressChanged() {
            PageMethods.Progress(progressSuccess);
        }

        // Updates the progress bar with the percent complete of the async process
        function progressSuccess(response) {
            $get('<%= progressPercent.ClientID %>').innerHTML = response + '%';
            $get('progressBar').style.width = response + '%';
            setTimeout("progressChanged()", 10);
        }

        // Cancels the async process
        function cancelAsync() {
            stopped = true;
            PageMethods.CancelAsync();
        }

        // Refreshes the the grid with the results using an async postback
        function refreshGrid(hiddenFieldID) {
            var hiddenField = $get(hiddenFieldID);
            if (hiddenField) {
                hiddenField.value = (new Date()).getTime();
                __doPostBack(hiddenFieldID, '');
            }
        }
       
   </script>
0
Comment
Question by:dthansen
  • 5
  • 4
11 Comments
 
LVL 15

Expert Comment

by:VincentPuglia
ID: 39691513
Hi,
my familiarity with ASP is limited to the zoo; however, is this:

$get("<%= panelMessages.ClientID %>" + "_MessagePanel").style.display = 'none';

where you expect to see the messages?  If so, where are you resetting 'display' to 'visible' or 'block'?
0
 
LVL 15

Expert Comment

by:VincentPuglia
ID: 39691515
and where is result's method defined?
 
 alert(result.get_message());
0
 

Author Comment

by:dthansen
ID: 39692902
$get("<%= panelMessages.ClientID %>" + "_MessagePanel").style.display = 'none';

isn't where I'm expecting to see the results,  that line is just hiding that control


where I am expecting to see messages is in this function where I pass in the result after the async call finishes

        function runAsyncSuccess(result) {
            if (!stopped) {
                $find('modalProgressBehaviorID').hide();
                $get('<%= btnConfirm.ClientID %>').disabled = '';
                $get('<%= btnCancel.ClientID %>').disabled = '';
                $get('<%= btnCalculate.ClientID %>').disabled = 'disabled';
                refreshGrid('<%=hfRefereshGrid.ClientID %>');
                alert(result.get_message());
            }
            stopped = false;
        }
 
I was thinking that this would pass the result back to runAsyncSuccess function

    Private Shared Function bgWorker_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) As String
        Return "ok"

    End Function

maybe that is incorrect

thanks
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 15

Expert Comment

by:VincentPuglia
ID: 39693175
Ok, but unless I'm reading it all wrong....
1) you are getting values, but where are you putting them?
as in:  var confirmBut = $get('<%= btnConfirm.ClientID %>').disabled = '';

2) you're presuming the alert has all of the information, where is result's get_message() method defined?    result.get_message());
0
 

Author Comment

by:dthansen
ID: 39693475
Hi Vincent

$get('<%= btnConfirm.ClientID %>').disabled = '';  
just disables the btnConfirm control on the aspx page.   $get is asp.net's shorthand for the javascript document.getElementById function.  no need to put that value anywhere

as far as I understand .get_message() is a built in javascript function that is supposed to extract any messages that are in the result object which is returned from the async call.

thanks
0
 
LVL 15

Expert Comment

by:VincentPuglia
ID: 39693533
sorry, but there is no obj.get_message() within 'vanilla' javascript.   I did see one mentioned for json
 msdn library
0
 

Author Comment

by:dthansen
ID: 39693628
ok, thanks Vincent.  I'll look into that
0
 
LVL 15

Expert Comment

by:VincentPuglia
ID: 39693649
In the meanwhile, you could try something like this:

get the values you need to look at, store them into a protected string (array, etc) and then send that string to javascript

var myValues = "<%= myProtectedString %>";

you can then alert(myValues)
0
 

Accepted Solution

by:
dthansen earned 0 total points
ID: 39731923
This has been resolved.

Here is what I needed to do:

changed the the RunWorkerCompleted Sub to

    ' Gets the result of the async call when completed and reports any errors that may have occurred
    Private Shared Sub bgWorker_Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        If e.Error IsNot Nothing Then
            asyncErrMessages = e.Error.Message
            Throw New Exception(asyncErrMessages)
        End If
    End Sub


In my aysnc routine if any errors occur I throw it from a try...catch.  the RunWorkerCompleted sub will catch the error

added this function that will return the error to the browser;
    <WebMethod()> _
    Public Shared Function AsyncErrors() As String
        Return asyncErrMessages
    End Function


added the following javascript to the page to display the error to the user:

        function runAsyncFailure() {
            PageMethods.AsyncErrors(asyncErrors)
        }

        function asyncErrors(result) {
            $get('btnCancelAsync').click();
            var msgPanel = $get("<%= panelMessages.ClientID %>" + "_MessagePanel");
            msgPanel.style.display = 'block';
            msgPanel.className = 'error';
            msgPanel.innerHTML = result;
        }
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article discusses the difference between strict equality operator and equality operator in JavaScript. The Need: Because JavaScript performs an implicit type conversion when performing comparisons, we have to take this into account when wri…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question