[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 895
  • Last Modified:

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>
0
dthansen
Asked:
dthansen
  • 5
  • 4
1 Solution
 
VincentPugliaCommented:
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
 
VincentPugliaCommented:
and where is result's method defined?
 
 alert(result.get_message());
0
 
dthansenAuthor Commented:
$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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
VincentPugliaCommented:
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
 
dthansenAuthor Commented:
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
 
VincentPugliaCommented:
sorry, but there is no obj.get_message() within 'vanilla' javascript.   I did see one mentioned for json
 msdn library
0
 
dthansenAuthor Commented:
ok, thanks Vincent.  I'll look into that
0
 
VincentPugliaCommented:
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
 
dthansenAuthor Commented:
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: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now