Link to home
Start Free TrialLog in
Avatar of dthansen
dthansen

asked on

asp.net BackGroundWorker RunWorkerCompleted

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>
Avatar of VincentPuglia
VincentPuglia

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'?
and where is result's method defined?
 
 alert(result.get_message());
Avatar of dthansen

ASKER

$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
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());
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
sorry, but there is no obj.get_message() within 'vanilla' javascript.   I did see one mentioned for json
 msdn library
ok, thanks Vincent.  I'll look into that
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)
ASKER CERTIFIED SOLUTION
Avatar of dthansen
dthansen

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial