• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 909
  • 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
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

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