Click here to Skip to main content
15,891,652 members
Articles / Web Development / XHTML

Lock ASP.NET Page and Show Animated Image While Waiting for a Long Post-Back

Rate me:
Please Sign up or sign in to vote.
4.83/5 (35 votes)
9 Apr 2009CPOL4 min read 266K   11.1K   119  
Lock page while post back
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.7.0
*/
YAHOO.namespace("tool");

/**
 * The YUI JavaScript profiler.
 * @module profiler
 * @namespace YAHOO.tool
 * @requires yahoo
 */

/**
 * Profiles functions in JavaScript.
 * @namespace YAHOO.tool
 * @class Profiler
 * @static
 */
YAHOO.tool.Profiler = {

    //-------------------------------------------------------------------------
    // Private Properties
    //-------------------------------------------------------------------------

    /**
     * Container object on which to put the original unprofiled methods.
     * @type Object
     * @private
     * @static
     * @property _container
     */
    _container : new Object(),

    /**
     * Call information for functions.
     * @type Object
     * @private
     * @static
     * @property _report
     */
    _report : new Object(),
    
    //-------------------------------------------------------------------------
    // Private Methods
    //-------------------------------------------------------------------------
    
    /**
     * Called when a method ends execution. Marks the start and end time of the 
     * method so it can calculate how long the function took to execute. Also 
     * updates min/max/avg calculations for the function.
     * @param {String} name The name of the function to mark as stopped.
     * @param {int} duration The number of milliseconds it took the function to
     *      execute.
     * @return {Void}
     * @private
     * @static
     */
    _saveData : function (name /*:String*/, duration /*:int*/){
        
        //get the function data
        var functionData /*:Object*/ = this._report[name];
    
        //increment the calls
        functionData.calls++;
        functionData.points.push(duration);

        //if it's already been called at least once, do more complex calculations
        if (functionData.calls > 1) {
            functionData.avg = ((functionData.avg*(functionData.calls-1))+duration)/functionData.calls;
            functionData.min = Math.min(functionData.min, duration);
            functionData.max = Math.max(functionData.max, duration);
        } else {
            functionData.avg = duration;
            functionData.min = duration;
            functionData.max = duration;
        }                             
    
    },

    //-------------------------------------------------------------------------
    // Reporting Methods
    //-------------------------------------------------------------------------    
    
    /**
     * Returns the average amount of time (in milliseconds) that the function
     * with the given name takes to execute.
     * @param {String} name The name of the function whose data should be returned.
     *      If an object type method, it should be 'constructor.prototype.methodName';
     *      a normal object method would just be 'object.methodName'.
     * @return {float} The average time it takes the function to execute.
     * @static
     */
    getAverage : function (name /*:String*/) /*:float*/ {
        return this._report[name].avg;
    },

    /**
     * Returns the number of times that the given function has been called.
     * @param {String} name The name of the function whose data should be returned.
     * @return {int} The number of times the function was called.
     * @static
     */
    getCallCount : function (name /*:String*/) /*:int*/ {
        return this._report[name].calls;    
    },
    
    /**
     * Returns the maximum amount of time (in milliseconds) that the function
     * with the given name takes to execute.
     * @param {String} name The name of the function whose data should be returned.
     *      If an object type method, it should be 'constructor.prototype.methodName';
     *      a normal object method would just be 'object.methodName'.
     * @return {float} The maximum time it takes the function to execute.
     */
    getMax : function (name /*:String*/) /*:int*/ {
        return this._report[name].max;
    },
    
    /**
     * Returns the minimum amount of time (in milliseconds) that the function
     * with the given name takes to execute.
     * @param {String} name The name of the function whose data should be returned.
     *      If an object type method, it should be 'constructor.prototype.methodName';
     *      a normal object method would just be 'object.methodName'.
     * @return {float} The minimum time it takes the function to execute.
     */
    getMin : function (name /*:String*/) /*:int*/ {
        return this._report[name].min;
    },

    /**
     * Returns an object containing profiling data for a single function.
     * The object has an entry for min, max, avg, calls, and points).
     * @return {Object} An object containing profile data for a given function.
     * @static
     */
    getFunctionReport : function (name /*:String*/) /*:Object*/ {
        return this._report[name];
    },

    /**
     * Returns an object containing profiling data for all of the functions 
     * that were profiled. The object has an entry for each function and 
     * returns all information (min, max, average, calls, etc.) for each
     * function.
     * @return {Object} An object containing all profile data.
     * @static
     */
    getFullReport : function (filter /*:Function*/) /*:Object*/ {
        filter = filter || function(){return true;};
    
        if (YAHOO.lang.isFunction(filter)) {
            var report = {};
            
            for (var name in this._report){
                if (filter(this._report[name])){
                    report[name] = this._report[name];    
                }
            }
            
            return report;
        }
    },

    //-------------------------------------------------------------------------
    // Profiling Methods
    //-------------------------------------------------------------------------   
    
    /**
     * Sets up a constructor for profiling, including all properties and methods on the prototype.
     * @param {string} name The fully-qualified name of the function including namespace information.
     * @param {Object} owner (Optional) The object that owns the function (namespace or containing object).
     * @return {Void}
     * @static
     */
    registerConstructor : function (name /*:String*/, owner /*:Object*/) /*:Void*/ {    
        this.registerFunction(name, owner, true);
    },

    /**
     * Sets up a function for profiling. It essentially overwrites the function with one
     * that has instrumentation data. This method also creates an entry for the function
     * in the profile report. The original function is stored on the _container object.
     * @param {String} name The full name of the function including namespacing. This
     *      is the name of the function that is stored in the report.
     * @param {Object} owner (Optional) The object that owns the function. If the function
     *      isn't global then this argument is required. This could be the namespace that
     *      the function belongs to, such as YAHOO.util.Dom, or the object on which it's
     *      a method.
     * @return {Void}
     * @method registerFunction
     */     
    registerFunction : function(name /*:String*/, owner /*:Object*/, registerPrototype /*:Boolean*/) /*:Void*/{
    
        //figure out the function name without namespacing
        var funcName /*:String*/ = (name.indexOf(".") > -1 ? name.substring(name.lastIndexOf(".")+1) : name);
        if (!YAHOO.lang.isObject(owner)){
            owner = eval(name.substring(0, name.lastIndexOf(".")));
        }
        
        //get the method and prototype
        var method /*:Function*/ = owner[funcName];
        var prototype /*:Object*/ = method.prototype;
        
        //see if the method has already been registered
        if (YAHOO.lang.isFunction(method) && !method.__yuiProfiled){
            
            //create a new slot for the original method
            this._container[name] = method;
            
            //replace the function with the profiling one
            owner[funcName] = function () {

                var start = new Date();     
                var retval = method.apply(this, arguments);
                var stop = new Date();
                
                YAHOO.tool.Profiler._saveData(name, stop-start);
                
                return retval;                
            
            };
            
            //copy the function properties over
            YAHOO.lang.augmentObject(owner[funcName], method);
            owner[funcName].__yuiProfiled = true;
            owner[funcName].prototype = prototype;
            this._container[name].__yuiOwner = owner;
            this._container[name].__yuiFuncName = funcName;        
        
            //register prototype if necessary
            if (registerPrototype) {            
                this.registerObject(name + ".prototype", prototype);          
            }
            
            //store function information
            this._report[name] = {
                calls: 0,
                max: 0,
                min: 0,
                avg: 0,
                points: []
            };        
        }
            
        return method;
    
    },
        
    
    /**
     * Sets up an object for profiling. It takes the object and looks for functions.
     * When a function is found, registerMethod() is called on it. If set to recrusive
     * mode, it will also setup objects found inside of this object for profiling, 
     * using the same methodology.
     * @param {String} name The name of the object to profile (shows up in report).
     * @param {Object} owner (Optional) The object represented by the name.
     * @param {Boolean} recurse (Optional) Determines if subobject methods are also profiled.
     * @return {Void}
     * @static
     */
    registerObject : function (name /*:String*/, object /*:Object*/, recurse /*:Boolean*/) /*:Void*/{
    
        //get the object
        object = (YAHOO.lang.isObject(object) ? object : eval(name));
    
        //save the object
        this._container[name] = object;
    
        for (var prop in object) {
            if (typeof object[prop] == "function"){
                if (prop != "constructor" && prop != "superclass"){ //don't do constructor or superclass, it's recursive
                    this.registerFunction(name + "." + prop, object);
                }
            } else if (typeof object[prop] == "object" && recurse){
                this.registerObject(name + "." + prop, object[prop], recurse);
            }
        }
    
    },    
    
    /**
     * Removes a constructor function from profiling. Reverses the registerConstructor() method.
     * @param {String} name The full name of the function including namespacing. This
     *      is the name of the function that is stored in the report.
     * @return {Void}
     * @method unregisterFunction
     */     
    unregisterConstructor : function(name /*:String*/) /*:Void*/{
            
        //see if the method has been registered
        if (YAHOO.lang.isFunction(this._container[name])){
        
            //get original data
            //var owner /*:Object*/ = this._container[name].__yuiOwner;
            //var funcName /*:String*/ = this._container[name].__yuiFuncName;
            //delete this._container[name].__yuiOwner;
            //delete this._container[name].__yuiFuncName;
            
            //replace instrumented function
            //owner[funcName] = this._container[name];
            //delete this._container[name];
            this.unregisterFunction(name, true);
       
        }

    
    },
    
    /**
     * Removes function from profiling. Reverses the registerFunction() method.
     * @param {String} name The full name of the function including namespacing. This
     *      is the name of the function that is stored in the report.
     * @return {Void}
     * @method unregisterFunction
     */     
    unregisterFunction : function(name /*:String*/, unregisterPrototype /*:Boolean*/) /*:Void*/{
            
        //see if the method has been registered
        if (YAHOO.lang.isFunction(this._container[name])){
        
            //check to see if you should unregister the prototype
            if (unregisterPrototype){
                this.unregisterObject(name + ".prototype", this._container[name].prototype);
            }
                
            //get original data
            var owner /*:Object*/ = this._container[name].__yuiOwner;
            var funcName /*:String*/ = this._container[name].__yuiFuncName;
            delete this._container[name].__yuiOwner;
            delete this._container[name].__yuiFuncName;
            
            //replace instrumented function
            owner[funcName] = this._container[name];
            
            //delete supporting information
            delete this._container[name];
            delete this._report[name];
       
        }
            
    
    },
    
    /**
     * Unregisters an object for profiling. It takes the object and looks for functions.
     * When a function is found, unregisterMethod() is called on it. If set to recrusive
     * mode, it will also unregister objects found inside of this object, 
     * using the same methodology.
     * @param {String} name The name of the object to unregister.
     * @param {Boolean} recurse (Optional) Determines if subobject methods should also be
     *      unregistered.
     * @return {Void}
     * @static
     */
    unregisterObject : function (name /*:String*/, recurse /*:Boolean*/) /*:Void*/{
    
        //get the object
        if (YAHOO.lang.isObject(this._container[name])){            
            var object = this._container[name];    
        
            for (var prop in object) {
                if (typeof object[prop] == "function"){
                    this.unregisterFunction(name + "." + prop);
                } else if (typeof object[prop] == "object" && recurse){
                    this.unregisterObject(name + "." + prop, recurse);
                }
            }
            
            delete this._container[name];
        }
    
    }
         

};
YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.7.0", build: "1799"});

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer TrafficTech
Canada Canada
Have technical skills that can be demonstrated and an ability to resolve complex problems quickly while working in a demanding, high pressure environment

Designs, plans, and coordinates software development work teams

Provides technical mentorship to project team members

Handles complex application features and technical designs for the development of new applications.

Write articles about ASP.net:
http://www.codeproject.com/KB/aspnet/SQLHelper20.aspx http://www.codeproject.com/KB/aspnet/DateAndTimePicker.aspx http://www.codeproject.com/KB/aspnet/SQLHelper20.aspx http://www.codeproject.com/KB/aspnet/WaitImageBoxWhilePagePost.aspx

Designs and implements the components, frameworks and layers required for complex application features

Understands and participate in all aspects of the Software Development Life Cycle

Relies on experience and judgment to plan and accomplish goals.

Ability to perform various programming activities (coding, testing, debugging, documenting, maintaining and supporting).

Ability to work independently with minimal supervision.

10 years’ experience in web software design and development.

SpecialtiesASP.net
SQL 2005
AJAX 1.0
Linq
C# 3.5
Microsoft Application Blocks
Java Script
Reporting Services
SQL SSIS
XML
Classic ASP

Comments and Discussions