Category Archives: DotNetGotcha

Awaiting for that Button click

Why wait when we can await?

I believe that most of C# developers know about the new language features for asynchronous programming with async and await keywords but how many of us are really exploiting them to full extent?

Recently i was watching the excellent C# Language Internals course on PluralSight.com by Bart De Smet and came across very cool idea of using Await to wait for Button to be clicked – which pushed me to write this post and share it with everyone.

By implementing a custom awaiter for Button (via extension methods) and hooking up to the Click handler we are able to await for that button to be clicked in very elegant way.

So innstead of manually adding Clicked event handler to each Button we hide that functionality in our awaiter and then we are able to write code this:

 private async void AwaitForButtonClicks()
 {
     await btn1;
 }

How do we implement custom awaiter?

Implementing custom awaiter surprisingly does not require you to inherit some class or implement an interface. Compiler is smart enough to recognize if you are implementing proper methods (either directly on the instance or via extension method) and if you do, then you can use await keyword on that type.

Cool thing about that is that you don’t need to own the class which you want to extend with awaiter,  same as in our case where we want to await for System.Windows.Control.Button which we don’t own (we could off course inherit it but if it would be sealed, we could still do it via extension methods).

Lets write the awaiter:

    public static class ButtonAwaiterExtensions
    {
        public static ButtonAwaiter GetAwaiter(this Button button)
        {
            return new ButtonAwaiter()
            {
                Button = button
            };
        }
    }

As you see we are adding the GetAwaiter method on the Button via extension method and returning the ButtonAwait which is just a class in which we will implement the actual await functionality (it could also be a struct instead of class). Also we pass the instance of the Button instance so that our ButtonAwaiter has something to attach to.

Compiler will recognize that we added this method (and also it will check if the ButtonAwaiter class that we return from it is implementing proper methods and interfaces) and because it will “see” all is implemented properly await keyword will start working for us.

In order for all this to work lets implement the ButtonAwaiter class:

    public class ButtonAwaiter : INotifyCompletion
    {
        public bool IsCompleted
        {
            get { return false; }
        }

        public void GetResult()
        {

        }

        public Button Button { get; set; }

        public void OnCompleted(Action continuation)
        {
            RoutedEventHandler h = null;
            h = (o, e) =>
            {
                Button.Click -= h;
                continuation();
            };
            Button.Click += h;
        }
    }

Our awaiter first of all returns false in the IsCompleted notifying the runtime that when we await for button, that it cannot return immediately, but only later after button is clicked.
And we take care of that in the OnCompleted method where runtime is subscribing with Action continuation to be called after awaiting is done – in other words after someone has clicked on the Button instance.
So in that method we create Click button handler and subscribe to the Click event and then inside that handler we unsubscribe (so we don’t get restart the await state machine every next time Button is clicked) and then we invoke the continuation action to notify everyone that our await is finished.

Note that GetResults does not return nothing since it would not make sense to return anything in our case – we are just waiting for the button click.

And that’s really all there is to it.

How to use this thing?

Now in our app we can await for multiple Buttons in which ever order we want and then do some action after Buttons are pressed in that specific order:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += (s, e) =>
            {
                AwaitForButtonClicks();
            };
        }

        private async void AwaitForButtonClicks()
        {
            await btn1;

            await btn2;

            await btn3;

            MessageBox.Show("Well done!");

            AwaitForButtonClicks();
        }
    }

So as you see in the Loaded even of the Window we call our async method that is awaiting for Button clicks and then show some message. And then we recursively start waiting again :)

Don’t forget that first await is waiting for click on the btn1 instance so even if you click some other button, code will still be waiting there for that specific click. Once first btn1 is clicked, execution moves to second line and awaits for btn2 to be clicked etc.

Button Awaiter in action

Ok we can use it but is it really useful?

I can think of scenarios where this could be really useful.

Besides freeing us from always writing the boilerplate code for subscribing to Click event of the button, there are more advantages.

Imagine a application that has many UI elements and interactions and you want to create a tutorial for your app that will run inside of the app.

Imagine app itself guiding the user through its own tutorial by highlighting certain Buttons or TextBoxes, and waiting for the user to click them or write some text in TextBox, or move some sliders of the app to understand how to setup parameters etc.

We could also use this in some game where user has to press some buttons in certain order etc.

Possibilities are endless and this Button awaiter is just a start – in one of the next posts I will write some more examples on how to await for different actions, how to pass parameters to await, so stay tuned.

I hope you find this useful and that it will push you to start exploring those (not so new) language features.

Download Visual Studio 2013 solution with source code for this post

msdn-logo

Dot Net Gotcha #2 – Loop variables and Closures

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

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…