roboblob

roboblob

(80 comments, 25 posts)

This user hasn't shared any profile information

Home page: http://blog.roboblob.com

Posts by roboblob
msdn-logo

Dot Net Gotcha #2 – Loop variables and Closures

2

This one is my favorite.

Can you guess the output of this simple console application:

    class Program
    {
        static void Main()
        {
            var actions = new List();

            for (var i = 0 ; i < 10; i++)             
            {                 
                var writeToConsoleAction = new Action(() =>
                    {
                        Console.WriteLine(i);
                    });
                actions.Add(writeToConsoleAction);
            }

            foreach (var action in actions)
            {
                action();
            }

            Console.ReadLine();
        }
    }

One would expect to see numbers from 0 to 9 but here is the actual output of the app:



OK that’s strange right?

It turns out its like that by design. What you have there is a Closure over the loop variable. And closures in C# are done around variables and not around specific values of those variables – so that means that lambda expression gets to use the actual reference to the closed variable.

Let me explain in little bit more detail:

In first loop we iterate increasing the counter variable from 0 to 9 and then use it in the lambda expression. That means each lambda gets its access to the counter via closure.

So at the end of this first loop, value of the counter is 10 (its 10 because we used post-increment operator: counter++, so in last iteration of the loop we increase counter to 10 and then check if its <10 and we see its not, so we exit the loop).

Afterwards we start executing those actions we created in first loop, and they all have a Closure over this same variable counter – which has value of 10 and therefore each action prints out its current value 10 to the console.

So it works as expected, once you know what to expect. :)

And this is really common mistake C# developers make.

How to fix it?

Solution is very simple once you know what is going on. All we need to do is this: instead of passing the variable counter to the lambda expression, create a local copy of this variable and pass this copy to the lambda instead of passing the counter.

That way, closure will each time be done around that copy variable that has current value of counter at that moment of execution, and this local copy value stay that way and will not be changed afterwards by the loop.

Later when the actions are executed (in the second loop), each will use their own closure around copy of the counter and therefore each will have its own different, expected value.

Here is the code that works as we expect:

    class Program
    {
        static void Main()
        {
            var actions = new List();

            for (var i = 0 ; i < 10; i++)             
            {                 
                    int counterCopy = i;                 
                    var writeToConsoleAction = new Action(() =>
                    {
                        Console.WriteLine(counterCopy);
                    });
                actions.Add(writeToConsoleAction);
            }

            foreach (var action in actions)
            {
                action();
            }

            Console.ReadLine();
        }
    }

As you see we create a copy of counter called counterCopy and pass this to the lambda expression each time.

Although this seems like old news if you knew it, there are many C# developers that are not aware of this behavior (or tend to forget it from time to time) so make sure to spread the word and always remember it.

By the way, the C# team is changing this in C# version 5 to work as one would expect but until then we just need to copy those loop variables manually :)

msdn-logo

Dot Net Gotcha #1 – List versus Collection constructor

1

Don’t Google it!

Do you know (without Googling it) what will this console application display when executed?

    class Program
    {
        static void Main(string[] args)
        {
            var originalNumbers = new List<int> { 1, 2, 3, 4, 5, 6 };

            var list = new List<int>(originalNumbers);
            var collection = new Collection<int>(originalNumbers);

            originalNumbers.RemoveAt(0);

            DisplayItems(list, "List items: ");
            DisplayItems(collection, "Collection items: ");

            Console.ReadLine();
        }

        private static void DisplayItems(IEnumerable<int> items, string title)
        {
            Console.WriteLine(title);
            foreach (var item in items)
                Console.Write(item);
            Console.WriteLine();
        }
    }

If you try to think logically, you expect that both List and Collection will contain numbers from 1 to 6 when they are displayed, right?

Wrong, otherwise this would not be a proper gotcha ;)

Here is the actual output of the application (surprise, surprise):

Do you know why?

Answer is actually very simple. If you check the MSDN documentation for Collection constructor that accepts generic IList you will see this text:

Initializes a new instance of the Collection class as a wrapper for the specified list.

That means that this constructor creates just a wrapper around the existing IList, so adding or removing items to the original list will also affect the new Collection we just created,  because its just a wrapper and uses original List under the hood.

On the other hand List constructor that accepts IEnumerable<T> behaves properly and does what you would logically expect it to do:

Initializes a new instance of the List<T> class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.

So when you create a new List and pass an existing List to its constructor it will create a proper new empty list, and then copy all the references from original List to the new List.

Because of that, the new List is ‘detached’ from the original and this is why it remains unchanged even if we modify the original List.

Moral of the story

This is simply how Microsoft made these two classes (i would not say its very consistent or good but who am i to judge, right?) and as long as you know it – its fine.

And if you don’t know this – it can bite you really hard.

All that you can do is to try to remember this, and also: RTFM.

Btw, did i said that this can be an excellent job interview question?   ;)

Until next Dot Net Gotcha, keep reading those manuals…

Windows-Phone-7-logo

Another way to close Windows Phone application from code

0

Correction

In my previous post on how to terminate the Windows Phone application i proposed a solution that is not really in accordance with Windows Phone Marketplace Technical Cerification Requirements (see requirement 5.1.2):

” An application that closes unexpectedly fails certification. ”

Even though I’m pretty sure that this requirement is not enforced since my apps use this approach and they were never rejected i decided to present another way.

Some good people suggested in comments of my previous post that you can terminate current application  simply by calling the XNA Game class Exit method like this:

using Microsoft.Xna.Framework;

namespace Roboblob
{
    public class AppLifetimeHelper
    {
        public void CloseApplication()
        {
            new Game().Exit();
        }
    }
}

The downside of this is that you need to add 2 XNA dll’s to your project:

  1. Microsoft.Xna.Framework
  2. Microsoft.Xna.Framework.Game
So there you have both approaches and you can choose which one is better for you until Microsoft exposes standardized way of closing application from code (i hope this will happen in Windows Phone 8 APIs).

Windows-Phone-7-logo

How to terminate your Windows Phone application programmatically?

5

21/08/2012 Update: 

There is another way to close the Windows Phone application without throwing exception see more details in my next post.

We want full power!

Its known that in Windows Phone API there is no easy way to terminate the current application from your code.

I guess makers of the platform did not wanted us developers to mingle with the application lifetime too much, phone should decide when an app is not needed and terminate it.

But i just simply cannot help myself, i always like to have full control, for example in my Offline Browser application i want to end the app if user presses the hardware Back Key multiple times in short time intervals.

Because there is this annoying situation when user goes navigating between the pages in your app (main screen, then settings, then about screen,

then again main screen etc) and then when he wants to terminate it he need to click the hardware back button N number of times in order to close it.

And even in some other situations its needed to force close the app, for example if some change in application settings requires app restart etc.

Show Us The Code!

So i decided to change this and wrote this simple AppLifetimeHelper that allows you to terminate your current app without any delay.

How it works is that it uses Application.Current.RootVisual and casts it to PhoneApplicationFrame that has RemoveBackEntry method that basically simulates

the users hardware Back Key press and then in endless loop it calls this method until the navigation back stack of the app is empty.

Then all we need to do is to call the GoBack method of the PhoneApplicationFrame and it will terminate the app since there are no more entries in the app Back Stack.

Simple or what?   8-)

So here is the code if you AppLifetimeHelper that you can freely use in your apps if you need this functionality:


using System.Linq;
using System.Windows;
using Microsoft.Phone.Controls;

namespace Roboblob
{
    public class AppLifetimeHelper
    {
        public void CloseApplication()
        {
            ClearApplicationNavigationBackStack();
            Root.GoBack();
        }

        private PhoneApplicationFrame _root;
        private PhoneApplicationFrame Root
        {
            get
            {
                if (_root == null)
                {
                    _root = Application.Current.RootVisual as PhoneApplicationFrame;
                }

                return _root;
            }
        }

        private void ClearApplicationNavigationBackStack()
        {
            if (Root == null)
            {
                return;
            }

            try
            {
                while (Root.BackStack.Any())
                {
                    Root.RemoveBackEntry();
                }
            }
            catch
            { }
        }
    }
}

And if you are really lazy today…

Here is the download link to the Visual Studio solution with Windows Phone application that uses this helper to terminate it self when a button is clicked…

roboblob's RSS Feed
Go to Top