Asynchronous programming Deep Dive part 2


 

Picking up from where I left off , I had promised to show you the code behind “both” button .The initial code is

   1: WebResponse Response = getResponse("http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk#");

   2:             int bbc =Int32.Parse( processBBCNews(Response).ToString());

   3:      

   4:  WebResponse Response1 = getResponse("https://news.google.com/news/feeds?ned=in&topic=h&output=rss");

   5:             int gn =Int32.Parse(  processGoogleNews(Response1).ToString());

   6:                      

   7:             int time_stop = System.Environment.TickCount;

   8:             //Computing the difference between the number of posts

   9:             textBox3.Text = (Math.Abs(bbc - gn)).ToString();

Now, the reduction in time can be felt the most in this part. Because we will designate 2 different threads to work on the 2 services.

Now to do this,if we blindly follow the previous method, we will end up with this .

   1: int time_start = System.Environment.TickCount;

   2:             Task<WebResponse> T1 = Task<WebResponse>.Factory.StartNew(()=>{

   3:             WebResponse Response = getResponse("http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk#");

   4:                 return Response;

   5:                 });

   6:            

   7:             Task<WebResponse> T2 = Task<WebResponse>.Factory.StartNew(()=>{

   8:             WebResponse Response = getResponse("https://news.google.com/news/feeds?ned=in&topic=h&output=rss");

   9:             

  10:             return Response;

  11:              });

  12:            Task<int> T1_next = T1.ContinueWith((antecedent) =>

  13:             {

  14:                 int gn = Int32.Parse(processGoogleNews(antecedent.Result).ToString());

  15:                 return gn;

  16:             },

  17:             TaskScheduler.FromCurrentSynchronizationContext());

  18:            Task<int> T2_next = T2.ContinueWith((antecedent) =>

  19:             {

  20:                 int bbc = Int32.Parse(processBBCNews(antecedent.Result).ToString());

  21:                 return bbc;

  22:             },

  23:                 TaskScheduler.FromCurrentSynchronizationContext()

  24:             );

  25:            

  26:               //Computing the difference between the number of posts

  27:             textBox3.Text = (Math.Abs(T1_next.Result - T2_next.Result)).ToString();

  28:           

  29:             int time_stop = System.Environment.TickCount;

  30:             label3.Text = (time_stop - time_start).ToString(); 

But this will not run. Infact this will freeze your application indefinitely? Why so?

The reason being, T1_next.Result executes before , T1 is actually finished . Now this is straight forward as we know that <task_name>.Result implicitly calls Task.Wait() and hence, it will freeze the UI thread and wait for the results.

But at the same time after T1 finishes, T1_next will be invoked, which is waiting at the local queue to be run on the UI thread. While the UI thread isn’t finished because it’s waiting for T1_next. Thus we have a deadlock. Always watch out for such deadlock, when you are dealing with synchronization contexts. So we need to do away with the waiting .

We need to change our code a bit

 

   1: int time_start = System.Environment.TickCount;

   2:             Task<ListBox> T1 = Task<ListBox>.Factory.StartNew(()=>{

   3:             WebResponse Response = getResponse("http://feeds.bbci.co.uk/news/world/rss.xml?edition=uk#");

   4:                 //Instead of returning the response we send the response to another processing function which does not update the UI thread

   5:             ListBox bbc = processBBCNews_new(Response);

   6:             Thread.Sleep(2000);

   7:             //The processing function returns a listbox 

   8:                 return bbc;

   9:                 });

  10:            

  11:             Task<ListBox> T2 = Task<ListBox>.Factory.StartNew(()=>{

  12:             WebResponse Response = getResponse("https://news.google.com/news/feeds?ned=in&topic=h&output=rss");

  13:  

  14:             ListBox gn = processGoogleNews_new(Response);

  15:             return gn;

  16:              });

  17:             //The trick is to wait for both T1 and T2 without blocking the UI thread                      

  18:             Task[] arr = { T1, T2 };

  19:             TaskFactory tf = new TaskFactory();

  20:             //Continue when all acts like a call back ,and does not fire wait on the UI thread,hence the UI is still responsive

  21:             tf.ContinueWhenAll(arr, (a) => {

  22:                 int count = 0, count1 = 0;

  23:                 

  24:                 foreach (string item in T1.Result.Items)

  25:                 {

  26:                     //The listbox returned is iterated to add those values to the UI listbox 

  27:                     count++;

  28:                     listBox1.Items.Add(item);

  29:                 }

  30:                 foreach (string item in T2.Result.Items)

  31:                 {

  32:                     count1++;

  33:                     listBox2.Items.Add(item);

  34:                 }

  35:                 //Computing the difference between the number of posts

  36:                 textBox3.Text = (Math.Abs(count1 - count)).ToString();

  37:                 int time_stop = System.Environment.TickCount;

  38:                 label3.Text = (time_stop - time_start).ToString();

  39:             

  40:             },new CancellationToken(),TaskContinuationOptions.None,TaskScheduler.FromCurrentSynchronizationContext());

If you go through the code,you would see I have used a continueWhenAll method.I have explained the reason.If you want to know more visit .

As I had promised, I have uploaded the entire app code here.

Advertisements

Dynamically set 100% content between header and footer in Jquery Mobile


Lot of people are building cross platform with JQuery Mobile.For the last 2-3 months I have been working on JQuery and making cross platform apps for my company.A few days ago,a weird problem stuck me. The no . of form elements and content within the viewport was very few.Hence the Toolbars instead of remaining fixed,came up as if floating in the air.To illustrate lets show a Jquery page with header nav and footer nav.

image

As you can see in the adjacent screenshot,instead of the view port being quite large,the footer is floating in the middle .The reason being very few content.This happened in mobile devices too.In windows Phone 7,the bar was floating in the middle.I have tested it with same result on Chrome and IE 10.

Now for desktop browser,we have an issue solution to the problem.

data-position=fixed  attribute will do the trick.

But unfortunately ,this doesn’t work on Windows Phone 7 and Android 2.3 browsers. The reason being the mobile browser do not have proper support for the CSS 3 position property .Hence even if we tinker with the position property,it will be of no avail.

Another solution would be to change the min-height of the content.It will definitely work,but since you are targeting more than one deices,with varying resolution and viewport size,this may not be a good idea.

So here I present a quick hack through which you can solve it .Wire up the function to the page show and page resize event and you will be good to go.

$(document).bind('pageshow',function(){
        
           
           adjustWindowheight($('#EditDiv')); //#editDiv is the id of the CONTENT part
        });

        adjustWindowheight = function (current_page_content) {
            //Check whether its WP7
            var isWp7 = window.navigator.userAgent.indexOf("IEMobile/9.0") != -1;
            current_page_content.each(function () {
                var containerHeight = parseInt($(this).css('height'));
                var windowHeight = parseInt(window.innerHeight);

                if (containerHeight + 118 < windowHeight) {
                    var newHeight = windowHeight - 118;
                    if (isWp7) {
                        //offset the page since WP7 wrongly reports page height
                        $(this).css('min-height', newHeight + 30 + 'px');
                    }
                    else {
                        $(this).css('min-height', newHeight + 'px');
                    }
                }
                else {
                    $(this).css('min-height', windowHeight + 'px');
                }

            });
        }

Now in this example,I have only hooked it to the pageshow method. I calculate the container height and the window height and I dynamically change the min height of the content.So basically for people looking for their content to fill 100% of the viewport,this would work for them .

Now windows phone does not report its container width properly ,hence we had to detect whether the browser is ie 9 of wp 7 and handle it that way. Any way hope the code helps

I will just leave you guys with the pic of the final result

image

Optimizing Selectors in JQuery.


jQuery uses a selector engine called Sizzle.Sizzle has various ways of selecting elements. Selecting elements is one of the fundamental part of jQuery, hence it’s important we learn how to optimize our selectors. jQuery selector Engine runs from right to left. Being specific on the left hand side has a lot less value than being specific on the right hand side.

$(“.parent .child”)//This is how the selector engine works.

A common misconception is that being accurate makes the selector works faster as it knows where to find the DOM element. But that is not the case. jQuery has a very different way in which it handles selecting by id or selecting by class.

<ul class=”listing”>

<li class=”bullet”>

<h3 class=”mainelement”> This is a test<h3>

</li>

<ul>

 

$(‘ul.listing li.bullet h3.mainelement’) //though is the most specific is not the fastest.

The fastest selector is simply the class name by itself.

$(.parent child)//Fastest

Anything else is telling jQuery to do more work than necessary. Starting from the right that is all that we need to get the set of elements.

<ul class=”listing”>

<li id=”bullet”>

<h3 class=”mainelement”> This is a test<h3>

</li>

<ul>

Now since we have an id. We can further bring down the time required by selecting with ID.

$(‘#bullet .mainelement’)//Sizzle operates differently when the first selector is ID

But to really speed things up, we can use

$(‘#bullet’).children(‘.mainelement’) or $(‘#bullet’).find(‘.mainelement’)

The latter being the fastest. To understand the discrepancy we must look into the jQuery Source. When the only part of the selector is an ID jQuery uses document.getElementById(id) which drastically reduces the time taken.

$(‘p#randomid’) //jQuery will use getElementsByTagName(), then iterate though the array of elements for the above selector.

var div = $(‘#randomId’);ßjQuery will use getElementById() for the above selector

From the source code we can see, the fastest selector is

$(‘ ‘)//Returns an empty jQuery object.

$(‘body’)//Next in line, jQuery converts this to document.body

$(‘#id’)//Third fastest, jQuery converts this to document.getElementById(‘id’)

 

Now to distinguish between children() and find(), Children only looks at the immediate children of the node, while find traverses the entire DOM below the node. But in general cases find is faster. children () internally makes calls to sibling(), filter(), and goes through a few more regexes than find() does. find () and children() fulfill different needs, but in the cases where find() and children() would output the same result, it’s better to use find().