<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msbdusers.net/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Tanzim Saqib on .NET discovery</title><link>http://msbdusers.net/blogs/tanzimsaqib/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>CallQueue: Implementing a Sequential Web Service Call Queue for AJAX application</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/11/19/7793.aspx</link><pubDate>Wed, 19 Nov 2008 10:10:35 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:7793</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/7793.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=7793</wfw:commentRss><description>&lt;p&gt;In AJAX based applications its common that user might end up breaking your AJAX calls by clicking on numerous places in very short interval of time. Let us assume there is a page where there are several of hyperlinks which make WebService calls and do some stuffs on callback. If user clicks on five hyperlinks being impatient or may be just for fun, there will be five different WebService calls made. All of those calls had the same parameters or UI state while they were invoked. But on completion of one or more WebService calls it may happen that the UI state or data passed to the rest of the WebServices calls no longer exist or expired, thus will be result in inconsistent UI behaviour and/or invalid data. This is one of the important scenarios an AJAX developer should consider when he designs an application. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Specification &lt;br&gt;&lt;/strong&gt;To address the scenario, I would prefer implementing a Sequential WebService Calls Queue which will be able to schedule the tasks/WebService calls and help keeping UI and data consistent over the AJAX calls. We should achieve the following features from this queue:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Enqueue any WebService call anytime in the application.  &lt;li&gt;Dequeue any previously queued call regardless of currently executing call and location in the application.  &lt;li&gt;Each WebService call should have an identifier so that we can track the call and dequeue anytime later by SSQ.dq(call_id).  &lt;li&gt;Each call should have a timeout value which will determine the maximum amount of time we will consider for that particular call before we invoke the next call, after that we will remove from the queue.  &lt;li&gt;A timer will act as scheduler but will not run forever. It should run only when necessary.  &lt;li&gt;Each call should be able to declare its completion at any time by notifyCompleted, so that the scheduler timer will not wait for the prior task and should dequeue the next call.  &lt;li&gt;notifyCompleted should also be optional. The currently running call should automatically be dequeued from the scheduler queue after the timeout of its own.  &lt;li&gt;Each call should be able to mark as replaceIfExists so that if user`s any activity already enqueued this call, should be replaced by the current one.  &lt;li&gt;The queue instance should be exclusively available to the user and all over the page, meaning that the same queue class will be used to serve the functionality in one page per user basis. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;The Usage &lt;br&gt;&lt;/strong&gt;You should be able to use this library as follows:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Include GenericQueue.js and SequentialServiceQueue.js to your project  &lt;li&gt;Add the reference in the pages that you want them to be used &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;We will be naming the class as SequentialServiceQueue and in short SSQ. Let us have a look at the WebService calls in Service Queue fashion:&lt;/p&gt; &lt;div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:fc2046a6-27d0-4752-a768-75c189e3c3e0" class="wlWriterSmartContent"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; id1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; SSQ.nq(&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;SomeMethod1&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;, 
    &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() 
    {
        &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Do some stuffs&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;        SomeWebService1.SomeMethod1(SomeParameters, onSomeMethodCallCompleted);
    });

&lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; onSomeMethodCallCompleted(result)
{
    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Do stuffs&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    SSQ.notifyCompleted(id1);    
}

&lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; id2 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; SSQ.nq(&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;SomeMethod2&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;, 
    &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() 
    {
        &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Do some stuffs&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;        SomeWebService2.SomeMethod2(SomeParameters, 
            &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(result)
            {
                &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Do stuffs&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;                SSQ.notifyCompleted(id2);
            });
    });&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can not only queue WebService calls, but also regular JavaScript codeblock:&lt;/p&gt;
&lt;div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6d67a192-97a6-4b98-a8d5-a17decee5809" class="wlWriterSmartContent"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; service_id1 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; SSQ.nq(&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;Service1&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;, 
    &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() 
    {
        &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Do some stuffs&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;        SSQ.notifyCompleted(service_id1);
    });&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;The GenericQueue &lt;br&gt;&lt;/strong&gt;To accomplish the SequentialServiceQueue, first of all we should define an all purpose GenericQueue class which will able to handle any queue requirement out of the box. The queue is fairly simple, just like old Computer Science data structure class. Here are few of the functions from the class:&lt;/p&gt;
&lt;div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3376f21b-d36c-474a-9973-b2befdf1374e" class="wlWriterSmartContent"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.nq &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(element) 
{
    array.push(element);
    &lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;rear;
}

&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.dq &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() 
{
    &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; element &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; undefined;

    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.is_empty()) 
    {
        element &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; array.shift();
        &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;rear;
    }

    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; element;
}

&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.for_each &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(func)
{
    &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;; i &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; rear; &lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;i)
        func(i, array&lt;img src="/emoticons/emotion-55.gif" alt="Idea" /&gt;);
}

&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.delete_at &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(index) 
{
    &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; array[index];

    &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; index;
    &lt;/span&gt;&lt;span&gt;while&lt;/span&gt;&lt;span&gt; (i &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; array.length) 
        array&lt;img src="/emoticons/emotion-55.gif" alt="Idea" /&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; array[&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;i];

    array &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; array.slice(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt;rear);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;The SequentialServiceQueue&lt;/strong&gt; &lt;br&gt;The following is how this class starts. You will notice here that the timer_id is for our scheduler timer, running_task indicates the currently executing call, interval is a variable for the timer_id which you can determine as your wish. interval is the knob of how fast or slow you want the scheduler to run. queue as you can understand is an GenericQueue instance we have just created above. Note that the GenericQueue is not a static class rather its a instance class unlike the SSQ. You have also noticed that the ms_when_last_call_made and ms_elapsed_since_last_call are pretty self-describing. get_random_id is reponsible for preparing new id for the newly enqueued call.&lt;/p&gt;
&lt;div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:b4286d51-b175-49f5-8944-59bed7e1fd96" class="wlWriterSmartContent"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; SequentialServiceQueue &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;
{
    timer_id: &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;,
    ms_when_last_call_made: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,          &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; milliseconds (readonly)&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    ms_elapsed_since_last_call: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,      &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; milliseconds (readonly)&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    running_task: &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;,
    interval: &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;,                       &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; milliseconds&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    queue: &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; GenericQueue(),

    get_random_id: &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() {
        &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; min &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;;
        &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; max &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;;
        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; Date().getTime() &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; (Math.round((max &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; min) &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; Math.random() &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; min));
    },&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From the code below, as soon as any new call is enqueued, we check for if it is allowed to replace if already exists in the queue with the same name. If found any, we just update that, otherwise we create a brand new task and enqueue and start our updater which is the scheduler in our case.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ae7c30d7-43e7-4af0-8770-8f7883c4cc68" class="wlWriterSmartContent"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;nq: &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(name, replaceIfExists, timeout, code) {
    &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.get_random_id();

    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (replaceIfExists) {
        &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; isFound &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;
        &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.queue.for_each(
            &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(index, element) {
                &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (element &lt;/span&gt;&lt;span&gt;!==&lt;/span&gt;&lt;span&gt; undefined &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; element &lt;/span&gt;&lt;span&gt;!==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt;undefined&lt;/span&gt;&lt;span&gt;'&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; element.name &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; name) {
                    element.id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; id;
                    element.replaceIfExists &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; replaceIfExists;
                    element.timeout &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; timeout;
                    element.code &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; code;
                    isFound &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;
                }
            });
    }

    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Enqueue new task&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;isFound &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;replaceIfExists) {
        &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.queue.nq(
            {
                id: id,
                name: name,
                replaceIfExists: replaceIfExists,
                timeout: timeout,
                code: code
            });
    }

    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; We have got new tasks, start the updater&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.startUpdater();

    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; id;
},&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The following is the core part of the class which is the scheduler. Inside startUpdater, it executes the block of code in every interval we defined before. And inside the looping code, we check for if there is already any running task, if yes we check for the timeout whether it should make a good timeout or not. Otherwise we let it run as it was. However, if there is no running task at this moment, we dequeue a task and start executing the code and set a starting time for that to keep track of how long it is being running.&lt;/p&gt;
&lt;div id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ca73c16b-189b-4e4e-8005-66e1353c8e9e" class="wlWriterSmartContent"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;detachTask: &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;(id) {
    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.dq(id);
    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.running_task &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;;
    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.ms_when_last_call_made &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;
    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.ms_elapsed_since_last_call &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;

    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; See if we are done with the queued tasks&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.queue.is_empty())
        &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.stopUpdater();
},

startUpdater: &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() {
    &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; _self &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;;
    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.timer_id &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {
        &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.timer_id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; setInterval(
            &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() {
                &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (_self.running_task &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {
                    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; We dont have any running task, lets make the first one&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;                    _self.running_task &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; _self.queue.dq();
                    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (_self.running_task &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {
                        _self.ms_when_last_call_made &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; Date().getTime();
                        _self.running_task.code();
                    }
                }
                &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {
                    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; We have a running task already&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;                    _self.ms_elapsed_since_last_call &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; Date().getTime() &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; _self.ms_when_last_call_made;

                    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Should the current task be skipped?&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (_self.ms_elapsed_since_last_call &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; _self.running_task.timeout)
                    &lt;/span&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt; Time's up. leave the task alone. Let other tasks start executing.&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span&gt;                        _self.detachTask(_self.running_task.id);
                }
            }, _self.interval);
    }
},

stopUpdater: &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;() {
    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.timer_id &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;) {
        clearInterval(&lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.timer_id)
        &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.timer_id &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;;
    }

    &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.queue &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; GenericQueue();
},&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Keep an eye on my blog for continued development and improvements, and download CallQueue from: &lt;a href="http://code.msdn.microsoft.com/callqueue"&gt;http://code.msdn.microsoft.com/callqueue&lt;/a&gt;&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=7793" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1012.aspx">AJAX</category></item><item><title>Fixing DevelopmentStorage's database cannot be found problem on Windows Azure</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/11/01/7769.aspx</link><pubDate>Sat, 01 Nov 2008 08:00:13 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:7769</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/7769.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=7769</wfw:commentRss><description>&lt;p&gt;This could be a common problem who are not using SQL Express. If you run an Azure application you may find it seeks for SQL Express instance in your machine if you do not have already. You may also find "An error occurred while processing this request." error due to this reason while you try creating tables from your models by StorageClient.TableStorage.CreateTablesFromModel. All you need to do is fire up Visual Studio and open the config file for DevelopmentStorage at C:\Program Files\Windows Azure SDK\v1.0\bin\DevelopmentStorage.exe.config. Now modify the connection string and the &lt;em&gt;dbServer&lt;/em&gt; attribute of the service tag for Table, and save.&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:743cfbb2-9483-4a59-ace5-c8aa678b4d2f"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;connectionStrings&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;add &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;DevelopmentStorageDbConnectionString&amp;quot;&lt;/span&gt;&lt;span&gt;
         connectionString&lt;/span&gt;&lt;span&gt;=&amp;quot;Data Source=.\SQLEXPRESS;Initial Catalog=DevelopmentStorageDb;Integrated Security=True&amp;quot;&lt;/span&gt;&lt;span&gt;
         providerName&lt;/span&gt;&lt;span&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;connectionStrings&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;
  
  &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;appSettings&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;    
    &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;add &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;=&amp;quot;ClientSettingsProvider.ServiceUri&amp;quot;&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;=&amp;quot;&amp;quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;appSettings&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;
  
  &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;developmentStorageConfig&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;services&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;service &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;Blob&amp;quot;&lt;/span&gt;&lt;span&gt;
               url&lt;/span&gt;&lt;span&gt;=&amp;quot;http://127.0.0.1:10000/&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;service &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;Queue&amp;quot;&lt;/span&gt;&lt;span&gt;
               url&lt;/span&gt;&lt;span&gt;=&amp;quot;http://127.0.0.1:10001/&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;service &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;=&amp;quot;Table&amp;quot;&lt;/span&gt;&lt;span&gt;
               url&lt;/span&gt;&lt;span&gt;=&amp;quot;http://127.0.0.1:10002/&amp;quot;&lt;/span&gt;&lt;span&gt;
               dbServer&lt;/span&gt;&lt;span&gt;=&amp;quot;localhost\SQLExpress&amp;quot;&lt;/span&gt;&lt;span&gt;/&amp;gt;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;services&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;
    ...
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Restart Visual Studio and open up the Azure project again, now you should be able to run the DevelopmentStorage with the existing database installation of your PC.&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=7769" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1007.aspx">.NET</category></item><item><title>jQuery intellisense in Visual Studio</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/10/27/7758.aspx</link><pubDate>Tue, 28 Oct 2008 03:35:30 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:7758</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/7758.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=7758</wfw:commentRss><description>&lt;p&gt;Those who are excited like me about the news of jQuery integration into Visual Studio, started adopting jQuery replacing ASP.NET AJAX Client side API. Microsoft also declared there will be a patch for Visual Studio which will support jQuery as well as intellisene for that. For the enthusiasts who just can't for it, here is the way how we can start developing using jQuery with full intellisense support inside Visual Studio 2008:&lt;/p&gt; &lt;p&gt;1. Download &lt;a title="jquery-1.2.6-vsdoc.js" href="http://jqueryjs.googlecode.com/files/jquery-1.2.6-vsdoc.js"&gt;jquery-1.2.6-vsdoc.js&lt;/a&gt;&lt;/p&gt; &lt;p&gt;2. Inside your JavaScript files, add a reference to it by placing the following line at the top of the JavaScript file:&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:75bfd113-eb5b-4d43-924d-27184b451c01"&gt;&lt;pre&gt;&lt;div&gt;&lt;span&gt;//&lt;/span&gt;&lt;span&gt;/ &amp;lt;reference path=&amp;quot;jquery-1.2.6-vsdoc.js&amp;quot; /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That's it. Enjoy!&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=7758" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1004.aspx">JavaScript</category></item><item><title>&amp;quot;.NET Research - Bangladesh&amp;quot; is live!</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/03/02/655.aspx</link><pubDate>Sun, 02 Mar 2008 20:42:34 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:655</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/655.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=655</wfw:commentRss><description>&lt;p&gt;This user group consists of .NET preachers from Bangladesh who perform extensive research on different aspects of the platform and futures of it that impact ranging from traditional way of software development to daily life coding. The purpose of the group is to discuss and share not limited to findings, facts only, but also patterns and best practices of current .NET framework and future additions to it with the developer community of Bangladesh. &lt;/p&gt; &lt;p&gt;&lt;br&gt;&lt;a href="http://dotnetbd.org/user/register"&gt;Free registration&lt;/a&gt; includes a personal blog which &lt;a href="http://dotnetbd.org/node/15"&gt;you can use with Windows Live Writer&lt;/a&gt;, forum access and other resources. Thanks for your coming here. Please feel yourself home! &lt;/p&gt; &lt;h1&gt;&lt;a href="http://www.dotnetbd.org" target="_blank"&gt;www.dotnetbd.org&lt;/a&gt;&lt;/h1&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=655" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1007.aspx">.NET</category></item><item><title>LINQ to Flickr</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/03/01/654.aspx</link><pubDate>Sat, 01 Mar 2008 16:07:49 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:654</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/654.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=654</wfw:commentRss><description>&lt;p&gt;One of my colleagues &lt;a href="http://weblogs.asp.net/mehfuzh"&gt;Mehfuz Hossain&lt;/a&gt; developed a wonderful open source project which allows you to query Flickr photos by LINQ, also lets you insert, delete photos directly to/from Flickr. You wonder how to extend LINQ in such an amazing way? It’s easy by writing your own custom LINQ provider, which was not-so-easy until he came up with another handy open source project named &lt;a href="http://www.codeplex.com/linqextender"&gt;LINQ Extender&lt;/a&gt;&lt;a href="http://www.codeplex.com/linqextender"&gt;&lt;/a&gt;. He did all the expression parsing stuff to ease our pain. Now you can make your own LINQ to Anything using this so easily.&lt;/p&gt; &lt;p&gt;For your heads up on LINQ extenders, here &lt;a href="http://dotnetslackers.com/articles/csharp/CreatingCustomLINQProviderUsingLinqExtender.aspx"&gt;he wrote an article&lt;/a&gt; and &lt;a href="http://www.codeplex.com/LINQFlickr"&gt;LINQ to Flickr&lt;/a&gt;, open source project is hosted at Codeplex.&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=654" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1006.aspx">LINQ</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1007.aspx">.NET</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1009.aspx">C#</category></item><item><title>A &amp;quot;transactional&amp;quot; generic DbHelper for LINQ to SQL</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/02/05/638.aspx</link><pubDate>Wed, 06 Feb 2008 07:18:13 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:638</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/638.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=638</wfw:commentRss><description>&lt;p&gt;In LINQ to SQL, the data model of a relational database is mapped to an object model expressed in the programming language of the developer. When the application runs, LINQ to SQL translates into SQL the language-integrated queries in the object model and sends them to the database for execution. When the database returns the results, LINQ to SQL translates them back to objects that you can work with in your own programming language. You may want to make a data access layer that separates the data operation from business layer like the following:&lt;/p&gt;&lt;pre class="code"&gt;DbHelper.Insert&amp;lt;&lt;font color="#2b91af"&gt;Student&lt;/font&gt;&amp;gt;(
    new &lt;font color="#2b91af"&gt;Student&lt;/font&gt;()
    {
        FirstName = &lt;span&gt;"Tanzim"&lt;/span&gt;,
        LastName = &lt;span&gt;"Saqib"&lt;/span&gt;,
        Email = &lt;span&gt;"me@TanzimSaqib.com"&lt;/span&gt;,
        Website = &lt;span&gt;"http://www.TanzimSaqib.com"&lt;/span&gt;&lt;/pre&gt;&lt;pre class="code"&gt;}, &lt;span&gt;true&lt;/span&gt;);    &lt;span&gt;// Use Transaction?&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;To make use of such transactional generic DbHelper, you might want to write a singeton DbHelper class like the following. You might notice that the class is singleton, it's static and the DataContext is being used is private, and only initialized using the connection string if not yet.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;public static class &lt;/span&gt;&lt;span&gt;DbHelper
&lt;/span&gt;{
    &lt;span&gt;private const string &lt;/span&gt;CONNECTION_CONFIG_NAME = &lt;span&gt;"StudentServerConnectionString"&lt;/span&gt;;

    &lt;span&gt;private static &lt;/span&gt;&lt;span&gt;StudentServerDataContext &lt;/span&gt;_StudentServerDataContext = &lt;span&gt;null&lt;/span&gt;;

    &lt;span&gt;public static &lt;/span&gt;&lt;span&gt;StudentServerDataContext &lt;/span&gt;GetDataContext()
    {
        &lt;span&gt;if&lt;/span&gt;(_StudentServerDataContext == &lt;span&gt;null&lt;/span&gt;)
            _StudentServerDataContext = &lt;span&gt;new &lt;/span&gt;&lt;span&gt;StudentServerDataContext&lt;/span&gt;(&lt;span&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[CONNECTION_CONFIG_NAME].ConnectionString);
        
        &lt;span&gt;return &lt;/span&gt;_StudentServerDataContext;
    }

    &lt;span&gt;public static void &lt;/span&gt;CleanUp()
    {
        _StudentServerDataContext.Dispose();
        _StudentServerDataContext = &lt;span&gt;null&lt;/span&gt;;
    }
    
    &lt;span&gt;// ... code edited to save space&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;On application wide error or on end you can dispose the context so CleanUp method is useful here. To implement an Insert method see the following. You will find I have used a TransactionScope which ensures that the transaction is taking place without any interruption. If there is really any error the scope.Complete() method never gets invoked. This is how it ensures that the code inside the TransactionScope is taking place as a transaction. It is available from .NET 2.0 framework.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;public static void &lt;/span&gt;Insert&amp;lt;T&amp;gt;(T t, &lt;span&gt;bool &lt;/span&gt;isTransactional) &lt;span&gt;where &lt;/span&gt;T : &lt;span&gt;class
&lt;/span&gt;{
    &lt;span&gt;if &lt;/span&gt;(isTransactional)
    {
        &lt;span&gt;using &lt;/span&gt;(&lt;span&gt;var &lt;/span&gt;scope = &lt;span&gt;new &lt;/span&gt;&lt;span&gt;TransactionScope&lt;/span&gt;())
        {
            Insert&amp;lt;T&amp;gt;(t);

            &lt;span&gt;// On any Exception, Complete() method won't be invoked.
            // So, the transaction will be automatically rollbacked.
            &lt;/span&gt;scope.Complete();
        }
    }
    &lt;span&gt;else
        &lt;/span&gt;Insert&amp;lt;T&amp;gt;(t);
}

&lt;span&gt;public static void &lt;/span&gt;Insert&amp;lt;T&amp;gt;(T t) &lt;span&gt;where &lt;/span&gt;T : &lt;span&gt;class
&lt;/span&gt;{
    &lt;span&gt;using &lt;/span&gt;(&lt;span&gt;var &lt;/span&gt;db = GetDataContext())
    {
        db.GetTable&amp;lt;T&amp;gt;().InsertOnSubmit(t);

        &lt;span&gt;try
        &lt;/span&gt;{
            db.SubmitChanges();
        }
        &lt;span&gt;catch &lt;/span&gt;(&lt;span&gt;Exception &lt;/span&gt;e)
        {
            &lt;span&gt;// TODO: log Exception
            &lt;/span&gt;&lt;span&gt;throw &lt;/span&gt;e;
        }
    }
}&lt;/pre&gt;I did not other methods as part of the CRUD implementation. The rest is left open for you to implement.&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=638" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1007.aspx">.NET</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1009.aspx">C#</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1006.aspx">LINQ</category></item><item><title>[New Article] 7 ways to do Performance Optimization of an ASP.NET 3.5 Web 2.0 portal</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/02/04/635.aspx</link><pubDate>Tue, 05 Feb 2008 05:35:41 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:635</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/635.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=635</wfw:commentRss><description>&lt;p&gt;Web 2.0 applications are widely developed. These applications often work with third party contents, aggregate them, make various use of them and then make something useful and meaningful to the users. For the past few years, developers were also engaged with such endeavors and a lot of their websites have not addressed performance issues, thus resulting in an unpleasant experience to the users.&lt;/p&gt; &lt;p&gt;Performance is a vast area and great results can never be achieved by a silver bullet. &lt;a href="http://dotnetslackers.com/articles/aspnet/SevenWaysToDoPerformanceOptimizationOfAnASPNET35Web20Portal.aspx" target="_blank"&gt;This article&lt;/a&gt; explores some of the key performance issues that can occur while developing a Web 2.0 portal using server side multithreading and caching. It also demonstrates model driven application development using Windows Workflow Foundation. &lt;/p&gt; &lt;p&gt;URL: &lt;a title="http://dotnetslackers.com/articles/aspnet/SevenWaysToDoPerformanceOptimizationOfAnASPNET35Web20Portal.aspx" href="http://dotnetslackers.com/articles/aspnet/SevenWaysToDoPerformanceOptimizationOfAnASPNET35Web20Portal.aspx"&gt;http://dotnetslackers.com/articles/aspnet/SevenWaysToDoPerformanceOptimizationOfAnASPNET35Web20Portal.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=635" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1007.aspx">.NET</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1006.aspx">LINQ</category></item><item><title>Write your own DOM friendly extension methods for HtmlElement in Volta</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/29/634.aspx</link><pubDate>Tue, 29 Jan 2008 20:26:53 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:634</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/634.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=634</wfw:commentRss><description>&lt;p&gt;I know there are &lt;strong&gt;GetById&lt;/strong&gt;, &lt;strong&gt;GetById&amp;lt;&amp;gt;&lt;/strong&gt; methods in Document object. But, I often miss a method that I feel should be in Volta, which iterates through its child nodes and find an element for me. Let us say, there is a HTML like the following:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;div &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;="divContainer"&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;Some text&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span&gt;div &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;="firstDiv"&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;Some more text&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span&gt;div &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;="secondDiv"&amp;gt;
        &lt;/span&gt;Okay, I gotta go now
    &lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span&gt;div &lt;/span&gt;&lt;span&gt;anyAttribute&lt;/span&gt;&lt;span&gt;="anyValue"&amp;gt;
        &lt;/span&gt;Babye
    &lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span&gt;div&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;The most important thing is, I can not get the last div by Document.&lt;strong&gt;GetById&lt;/strong&gt;, because instead of id I chose &lt;strong&gt;anyAttribute&lt;/strong&gt;. So, I wrote my own extension method which can run into not only Div but also any &lt;strong&gt;HtmlElement&lt;/strong&gt;, and can find me the desired &lt;strong&gt;HtmlElement&lt;/strong&gt; inside the prior one with the &lt;strong&gt;anyAttribute&lt;/strong&gt; and &lt;strong&gt;anyValue&lt;/strong&gt;. To make my intention clear, I'd like to show how I'd like to use that extension method: &lt;pre class="code"&gt;&lt;span&gt;var &lt;/span&gt;divContainer = Document.GetById&amp;lt;&lt;span&gt;Div&lt;/span&gt;&amp;gt;(&lt;span&gt;"divContainer"&lt;/span&gt;);
&lt;span&gt;var &lt;/span&gt;anyDiv = divContainer.Find&amp;lt;&lt;span&gt;Div&lt;/span&gt;&amp;gt;(&lt;span&gt;"anyAttribute"&lt;/span&gt;, &lt;span&gt;"anyValue"&lt;/span&gt;);

&lt;span&gt;if&lt;/span&gt;(anyDiv != &lt;span&gt;null&lt;/span&gt;)
    anyDiv.InnerHtml += &lt;span&gt;"guys!"&lt;/span&gt;;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;So, I'd like to call my extension method &lt;strong&gt;Find&amp;lt;&amp;gt;&lt;/strong&gt; which will take the type I'm looking for (in this case a Div) and that &lt;strong&gt;HtmlElement&lt;/strong&gt; should have an attribute "&lt;strong&gt;anyAttribute&lt;/strong&gt;" that contains "&lt;strong&gt;anyValue&lt;/strong&gt;". Here is how I make up the extension method: &lt;pre class="code"&gt;&lt;span&gt;public static class &lt;/span&gt;&lt;span&gt;HtmlExtensions
&lt;/span&gt;{
    &lt;span&gt;public static &lt;/span&gt;T Find&amp;lt;T&amp;gt;(&lt;span&gt;this &lt;/span&gt;T parent, &lt;span&gt;string &lt;/span&gt;attribute, &lt;span&gt;string &lt;/span&gt;value)
        &lt;span&gt;where &lt;/span&gt;T : &lt;span&gt;HtmlElement
    &lt;/span&gt;{
        &lt;span&gt;var &lt;/span&gt;element = parent.FirstChild; 

        &lt;span&gt;while&lt;/span&gt;(element != &lt;span&gt;null&lt;/span&gt;)
            &lt;span&gt;if &lt;/span&gt;(element.IsProper&amp;lt;T&amp;gt;(attribute, value))
                &lt;span&gt;return &lt;/span&gt;element &lt;span&gt;as &lt;/span&gt;T;
            &lt;span&gt;else
                &lt;/span&gt;element = element.NextSibling; 

        &lt;span&gt;return null&lt;/span&gt;;
    }

    &lt;span&gt;public static bool &lt;/span&gt;IsProper&amp;lt;T&amp;gt;(&lt;span&gt;this &lt;/span&gt;&lt;span&gt;DomNode &lt;/span&gt;element, &lt;span&gt;string &lt;/span&gt;attribute, &lt;span&gt;string &lt;/span&gt;value)
        &lt;span&gt;where &lt;/span&gt;T : &lt;span&gt;HtmlElement
    &lt;/span&gt;{
        &lt;span&gt;if &lt;/span&gt;(element.GetType() == &lt;span&gt;typeof&lt;/span&gt;(T) &amp;amp;&amp;amp;
            element.Attributes != &lt;span&gt;null &lt;/span&gt;&amp;amp;&amp;amp;
            element.Attributes.GetNamedItem(attribute) != &lt;span&gt;null &lt;/span&gt;&amp;amp;&amp;amp;
            element.Attributes.GetNamedItem(attribute).Value == value)

            &lt;span&gt;return true&lt;/span&gt;;

        &lt;span&gt;return false&lt;/span&gt;;
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;This method can iterate only one depth. Multi depth implementation can be done by running a simple DFS which is left to you guys. Note one thing, I have called one extension method "&lt;strong&gt;IsProper&lt;/strong&gt;" inside another extension method, and there is no harm in it. So, this is how you can add your own extension methods to the &lt;strong&gt;HtmlElement&lt;/strong&gt;.&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=634" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1008.aspx">Volta</category></item><item><title>Appearing on Microsoft Volta team blog</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/26/631.aspx</link><pubDate>Sat, 26 Jan 2008 22:03:12 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:631</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/631.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=631</wfw:commentRss><description>&lt;p&gt;Microsoft Volta team blogged about me and one of my articles: &lt;a href="http://labs.live.com/volta/blog/Volta+How+To+Flickr+Widget.aspx" target="_blank"&gt;http://labs.live.com/volta/blog/Volta+How+To+Flickr+Widget.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=631" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1008.aspx">Volta</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1012.aspx">AJAX</category></item><item><title>[New Article] ASP.NET AJAX Best Practices</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/26/625.aspx</link><pubDate>Sat, 26 Jan 2008 19:21:18 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:625</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/625.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=625</wfw:commentRss><description>&lt;p&gt;While we develop AJAX applications, we often carelessly ignore giving up bad practices, which cause effects which are not so significantly visible when the site is not so large in volume. But, it’s often severe performance issue when it is the case for sites that make heavy use of AJAX technologies such as Pageflakes, NetVibes etc.  &lt;p&gt;There are so many AJAX widgets in one page that little memory leak issues combined may even result the site crash into very nasty “Operation aborted”. There are a lot of WebService calls, lot of iterations among collection so that inefficient coding in a whole lead to make site very heavy, browser eats up a lot of memory, requires very costly CPU cycles, and ultimately causes unsatisfactory user experience. In this article many of such issues are demonstrated in the context of ASP.NET AJAX.  &lt;p&gt;&lt;a title="http://www.codeproject.com/KB/ajax/AspNetAjaxBestPractices.aspx" href="http://www.codeproject.com/KB/ajax/AspNetAjaxBestPractices.aspx" target="_blank"&gt;http://www.codeproject.com/KB/ajax/AspNetAjaxBestPractices.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=625" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1014.aspx">Performance</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1012.aspx">AJAX</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1011.aspx">Articles</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1004.aspx">JavaScript</category></item><item><title>HttpRequestFactory vs. XMLHttpRequest in Volta</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/25/616.aspx</link><pubDate>Fri, 25 Jan 2008 17:16:13 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:616</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/616.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=616</wfw:commentRss><description>&lt;p&gt;HttpRequestFactory was designed for use by tiersplitting internally and was not supposed to be exposed as part of the Volta API as Danny van Velzen from Microsoft Volta team told me today. So, its better if you use XMLHttpRequest instead because this factory class might not show up in the later releases. You will find this class in Microsoft.LiveLabs.Volta.Xml namespace.&amp;nbsp; As like as JavaScript's one, in this .NET version you can also Open URL, specify method name, and of course pass credentials. You can track response text, xml, status code, status text and also you can abort. &lt;/p&gt; &lt;p&gt;To retrieve your content, you must subscribe to ReadyStateChange event with a HtmlEventHandler which you can find in Microsoft.LiveLabs.Volta.Html namespace and check the status code. If it is 200 that means "HTTP OK", you can take the ResponseText or ResponseXML. See this example:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;string &lt;/span&gt;content = &lt;span&gt;string&lt;/span&gt;.Empty;
&lt;span&gt;var &lt;/span&gt;request = &lt;span&gt;new &lt;/span&gt;&lt;span&gt;XMLHttpRequest&lt;/span&gt;();

request.ReadyStateChange += &lt;span&gt;delegate&lt;/span&gt;()
{
    &lt;span&gt;if &lt;/span&gt;(request.Status == 200)
        content = request1.ResponseText;
};

request.Open(&lt;span&gt;"POST"&lt;/span&gt;, &lt;span&gt;"http://tanzimsaqib.com/feed/"&lt;/span&gt;, &lt;span&gt;true&lt;/span&gt;);&lt;/pre&gt;However, you cannot fetch cross domain content by XMLHttpRequest. The Volta compiler creates client side JavaScript XMLHttpRequest and lets developers write code in .NET friendly way. So, I do not think there is any way to retrieve cross domain content in Volta, and leaving us on the same old HttpRequest class.&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=616" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1007.aspx">.NET</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1008.aspx">Volta</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1009.aspx">C#</category></item><item><title>[New Article] Building a Volta Control : A Flickr Widget</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/18/615.aspx</link><pubDate>Fri, 18 Jan 2008 20:38:52 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:615</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/615.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=615</wfw:commentRss><description>&lt;p&gt;This is my first article which is based on the first CTP of Volta considering its current limitations. You will see how you can create a Volta control that the compiler can convert into an AJAX Widget without requiring us writing a single line of JavaScript code: &lt;a title="http://dotnetslackers.com/articles/aspnet/BuildingAVoltaControlAFlickrWidget.aspx" href="http://dotnetslackers.com/articles/aspnet/BuildingAVoltaControlAFlickrWidget.aspx"&gt;http://dotnetslackers.com/articles/aspnet/BuildingAVoltaControlAFlickrWidget.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=615" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1011.aspx">Articles</category></item><item><title>ASP.NET AJAX Best Practices: Avoid String concatenation, use Array instead</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/15/630.aspx</link><pubDate>Tue, 15 Jan 2008 09:36:26 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:630</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/630.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=630</wfw:commentRss><description>&lt;p&gt;Don't you think the following block of code has written keeping every possible good practice in mind? Any option for performance improvement?&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;function &lt;/span&gt;pageLoad()
{
    &lt;span&gt;var &lt;/span&gt;stringArray = &lt;span&gt;new &lt;/span&gt;Array();
    
    &lt;span&gt;// Suppose there're a lot of strings in the array like:
    &lt;/span&gt;stringArray.push(&lt;span&gt;'&amp;lt;div&amp;gt;'&lt;/span&gt;);
    stringArray.push(&lt;span&gt;'some content'&lt;/span&gt;);
    stringArray.push(&lt;span&gt;'&amp;lt;/div&amp;gt;'&lt;/span&gt;);
    
    &lt;span&gt;// ... code edited to save space
    
    &lt;/span&gt;&lt;span&gt;var &lt;/span&gt;veryLongHtml = $get(&lt;span&gt;'divContent'&lt;/span&gt;).innerHTML;
    &lt;span&gt;var &lt;/span&gt;count = stringArray.length;
    
    &lt;span&gt;for&lt;/span&gt;(&lt;span&gt;var &lt;/span&gt;i=0; i&amp;lt;count; ++i)
        veryLongHtml += stringArray&lt;img src="/emoticons/emotion-55.gif" alt="Idea" /&gt;;    
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Well, as you see the &lt;code&gt;innerHTML &lt;/code&gt;of the div has been cached so that browser will not have to access the DOM every time while iterating through &lt;code&gt;stringArray&lt;/code&gt;, thus costlier DOM methods are being avoided. But, inside the body of the loop the JavaScript interpreter has to perform the following operation:&lt;/p&gt;&lt;pre class="code"&gt;veryLongHtml = veryLongHtml + stringArray&lt;img src="/emoticons/emotion-55.gif" alt="Idea" /&gt;;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;And the veryLongHtml contains quite a large string which means in this operation the interpreter will have to retrieve the large string and then concatenate with the stringArray elements in every iteration. One very short yet efficient solution to this problem is using join method of the array like the following, instead of looping through the array:&lt;/p&gt;&lt;pre class="code"&gt;veryLongHtml = stringArray.join(&lt;span&gt;''&lt;/span&gt;); &lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;However, this is very efficient than the one we were doing, since it joins the array with smaller strings which requires less memory.&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=630" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1014.aspx">Performance</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1012.aspx">AJAX</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1004.aspx">JavaScript</category></item><item><title>How to solve: Server Controls can't be accessed in View's code-behind in ASP.NET MVC</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/14/614.aspx</link><pubDate>Mon, 14 Jan 2008 20:38:19 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:614</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/614.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=614</wfw:commentRss><description>&lt;p&gt;It's still long way to go for a final release of ASP.NET MVC, the one I've been using right now is just a December CTP. But, like me you might be experiencing this confusing problem. The server controls that you put in a View (ViewContentPage) can not be found in code-behind page. The reason behind it is - the Views don't have a back-end designer code file. I believe it's just a bug or they could not find time to fix/look into it. I'm sure it will be fixed in any of the upcoming versions.&lt;/p&gt;  &lt;p&gt;To enable this, switch to Solution Explorer, right click on the View you are interested in, and choose Convert to Web Application. Now, you will find the server controls in code-behind file.&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=614" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1010.aspx">MVC</category></item><item><title>ASP.NET AJAX Best Practices: Introduce function delegates</title><link>http://msbdusers.net/blogs/tanzimsaqib/archive/2008/01/13/628.aspx</link><pubDate>Sun, 13 Jan 2008 09:33:55 GMT</pubDate><guid isPermaLink="false">63af0bde-72d8-4abb-a2a9-63148ff32434:628</guid><dc:creator>TanzimSaqib</dc:creator><slash:comments>0</slash:comments><comments>http://msbdusers.net/blogs/tanzimsaqib/comments/628.aspx</comments><wfw:commentRss>http://msbdusers.net/blogs/tanzimsaqib/commentrss.aspx?PostID=628</wfw:commentRss><description>&lt;p&gt;Take a look at the following loop. This loop calls a function in each iteration and the function does some stuffs. Can you think of any performance improvement idea?&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;for&lt;/span&gt;(&lt;span&gt;var &lt;/span&gt;i=0; i&amp;lt;count; ++i)
    processElement(elements&lt;img src="/emoticons/emotion-55.gif" alt="Idea" /&gt;);&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Well, for sufficiently large array, function delegates may result in significant performance improvement to the loop.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span&gt;var &lt;/span&gt;delegate = processElement;
    
&lt;span&gt;for&lt;/span&gt;(&lt;span&gt;var &lt;/span&gt;i=0; i&amp;lt;count; ++i)
    delegate(elements&lt;img src="/emoticons/emotion-55.gif" alt="Idea" /&gt;);&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The reason behind performance improvement is, JavaScript interpreter will use the function as local variable and will not lookup in its scope chain for the function body in each iteration.&lt;/p&gt;&lt;img src="http://msbdusers.net/aggbug.aspx?PostID=628" width="1" height="1"&gt;</description><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1014.aspx">Performance</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1012.aspx">AJAX</category><category domain="http://msbdusers.net/blogs/tanzimsaqib/archive/category/1004.aspx">JavaScript</category></item></channel></rss>