Home > Net >  how can i get this c# server side wait window to quit when exporting is finished?
how can i get this c# server side wait window to quit when exporting is finished?

Time:09-22

Team!!

I have a website that let's people download data into an excel or pdf file. The download takes long enough that I want to display a "Please Wait" modal while the processing is happening. I found some code that does this, but the problem is it just counts from 1 to 100 and then quits. I'd like to alter that so that it displays until the download is complete.

When the use clicks the button to begin the export, the expot_click function is called. The WorkerMethod function below it gets passed into the class and is where the count from 1 to 100 is occurring. I'm not sure what to change, or where to change it.

protected void export_click(object sender, EventArgs e)
{
    string exportType = hidExportType.Value;
    string exportSections = hidSections.Value;
    string exportStudents = hidStudents.Value;

    //Display a "Please Wait" message while the download is happening
    object result = WaitWindow.Show(this.WorkerMethod);

    switch (exportType)
    {
        case "csv":
            export_csv(exportSections, exportStudents);
            break;
        case "excel":
            export_excel(exportSections, exportStudents);
            break;
        case "pdf":
            export_pdf(exportSections, exportStudents);
            break;
        default:
            break;
    }

    //I'm guessing here is where I'd want to do something to make the wait display quit? 

}

private void WorkerMethod(object sender, Jacksonsoft.WaitWindowEventArgs e)
{
    // Do something
    for (int progress = 1; progress <= 100; progress  )
    {
        System.Threading.Thread.Sleep(20);

        // Update the wait window message
        e.Window.Message = string.Format
        ("Please wait ... {0}%", progress.ToString().PadLeft(3));
    }

    // Use the arguments sent in
    if (e.Arguments.Count > 0)
    {
        // Set the result to return
        e.Result = e.Arguments[0].ToString();
    }
    else
    {
        // Set the result to return
        e.Result = "Hello World";
    }
}

Below is the class that gets called:

/*
 * Created by SharpDevelop.
 * User: mjackson
 * Date: 05/03/2010
 * Time: 09:36
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Jacksonsoft
{
    /// <summary>
    /// Displays a window telling the user to wait while a process is executing.
    /// </summary>
    public class WaitWindow
    {

        /// <summary>
        /// Shows a wait window with the text 'Please wait...' while executing the passed method.
        /// </summary>
        /// <param name="workerMethod">Pointer to the method to execute while displaying the wait window.</param>
        /// <returns>The result argument from the worker method.</returns>
        public static object Show(EventHandler<WaitWindowEventArgs> workerMethod){
            return WaitWindow.Show(workerMethod, null);
        }
    
        /// <summary>
        /// Shows a wait window with the specified text while executing the passed method.
        /// </summary>
        /// <param name="workerMethod">Pointer to the method to execute while displaying the wait window.</param>
        /// <param name="message">The text to display.</param>
        /// <returns>The result argument from the worker method.</returns>
        public static object Show(EventHandler<WaitWindowEventArgs> workerMethod, string message){
            WaitWindow instance = new WaitWindow();
            return instance.Show(workerMethod, message, new List<object>());
        }

        /// <summary>
        /// Shows a wait window with the specified text while executing the passed method.
        /// </summary>
        /// <param name="workerMethod">Pointer to the method to execute while displaying the wait window.</param>
        /// <param name="message">The text to display.</param>
        /// <param name="args">Arguments to pass to the worker method.</param>
        /// <returns>The result argument from the worker method.</returns>
        public static object Show(EventHandler<WaitWindowEventArgs> workerMethod, string message, params object[] args){
            List<object> arguments = new List<object>();
            arguments.AddRange(args);
        
            WaitWindow instance = new WaitWindow();
            return instance.Show(workerMethod, message, arguments);
        }

        #region Instance implementation

        private WaitWindow(){}

        private WaitWindowGUI _GUI;
        internal delegate void MethodInvoker<T>(T parameter1);
        internal EventHandler<WaitWindowEventArgs> _WorkerMethod;
        internal List<object> _Args;

        /// <summary>
        /// Updates the message displayed in the wait window.
        /// </summary>
        public string Message{
            set{
                this._GUI.Invoke(new MethodInvoker<string>(this._GUI.SetMessage), value);
            }
        }

        /// <summary>
        /// Cancels the work and exits the wait windows immediately
        /// </summary>
        public void Cancel(){
            this._GUI.Invoke(new MethodInvoker(this._GUI.Cancel), null);
        }
    
        private object Show(EventHandler<WaitWindowEventArgs> workerMethod, string message, List<object> args){
            //  Validate Parameters
            if (workerMethod == null){
                throw new ArgumentException("No worker method has been specified.", "workerMethod");
            } else {
                this._WorkerMethod = workerMethod;
            }
        
            this._Args = args;
        
            if (string.IsNullOrEmpty(message)){
                message = "Please wait...";
            }
        
            //  Set up the window
            this._GUI = new WaitWindowGUI(this);
            this._GUI.MessageLabel.Text = message;
        
            //  Call it
            this._GUI.ShowDialog();

            object result = this._GUI._Result;
        
            //  clean up
            Exception _Error = this._GUI._Error;
            this._GUI.Dispose();
        
            //  Return result or throw and exception
            if (_Error != null){
                throw _Error;
            } else {
                return result;
            }
        }
    
        #endregion Instance implementation

    }
}

Any suggestions on what to do to get this working would be greatly appreciated!!

CodePudding user response:

You can't use a server side window.

but, what you can do is pop or display a dialog WHEN the user clicks on the button. That pop dialog will stay open while the web page is up on the server being processed. When the server page is done, then that new fresh server page is then send back to the client side browser and thus the display message will go away on its own.

So, say your button to start process is a simple button. When clicked on that "longer" server side code runs.

So, you keep the buttion, but add a client side script to pop up a dialog message. In this case we will use a jQuery.UI dialog. So, you will need in the web page jQquery, and jQuery.UI.

So, now the simple button code becomes this:

        <asp:Button ID="cmdBigProcess" runat="server" Text="Start the reactor!" 
            OnClientClick="showait();return true;"
            OnClick="cmdBigProcess_Click" />

        <div id="mywait" style="display:none;border:solid">
            <h2>Big process running - please wait</h2>
        </div>
        <script>
            function showait() {
                // lets pop jquery.UI dialog
                var mydiv = $("#mywait")
                mydiv.dialog({
                    modal: true, appendTo: "form",
                    title: "Please wait", closeText: "",
                    width: "400px"
                });
            }
        </script>

So, we added a simple "div" that will hold the message.

Now, when you click on the button, the "on client click" code runs FIRST, and displays the dialog, then your server side code runs. As noted, we don't have to dismiss or do anything to the dialog, since when the web page is posted, it travels up to the server. The code behind runs (may or may not change thing on the web page), and THEN when the page is done, the whole web page now travels back down to the web side, browser re-plots and re-loads the web page (this is the so called round trip, or often called the page life-cycle. it is BEYOND critical that you grasp and understand this round trip concept. Your code behind NEVER directly interacts with the user. But upon hitting a buttion, the WHOLE web page travels up to server, code runs. And EVEN when the code modifies the controls and things in the web page? They will NOT show up, NOT update, and user will not see any changes to that web page until ALL YOUR code behind is done. Once code behind is done, then the WHOLE page makes the trip back to browser and is re-loaded.

So, the re-load of the page is what in fact will case the popped up dialog to be dismissed. Note that jQuery.UI dialogs (and most web dialogs) do NOT halt code when called - code continues.

The result looks like this:

enter image description here

  • Related