Queuing up code to run, and closures in .NET

I recently ran across an issue where I would like to queue up code to run when a certain condition is met. Now, you could approach this in several ways. However, in this case, what immediately started coming out of my fingers onto the keyboard was to have a Queue<Action>, that is, a queue which stores delegates, or function pointers.

mx3CCBA

The concept would be that I would enqueue function pointers. Later on when the specified condition was met, I would dequeue the function pointers and execute them. I’m not sure why I gravitated to this particular approach, but for this particular problem, this seemed like a logical conclusion.

For example, you might enqueue arbitrary code like this:

mx32BAD

In other words, there is not a function pointer stored in that queue. It contains the arbitrary code from above. It’s important to understand that this code hasn’t run yet, but the pointer to it has been stored.

After an arbitrary amount of time, you could later dequeue these function pointers/delegates/anonymous functions and execute that code with something like this (calling .Invoke() executes the code):

mx3ACF3

This might seem underwhelming and this is only useful in some scenarios. But hold on, it gets a little more complicated.

What if code inside of your anonymous method used variables from an outer scope. What if that anonymous method uses arguments which were passed into that method or local variables from that method. Later on (it could be days later), what happens when I go to Invoke/execute that anonymous function? That “context” is no longer there – so…. what happens?

Closures:
This concept is called “closures”. As I understand it, the run-time creates a in-memory class basically to house the code to execute and the context that it needs. So, if you used a local variable in your anonymous method, the run-time gets a copy of it and stores it along with your anonymous method. It does this for any context that you use, inside of that delegate.

To test this, I created some sample code:

mx3221B

You might notice that I even have this setup code executing in it’s own method (RunThoseThings). We know that when we leave that method, it is taken off the stack, and those variables are lost. I wanted to be sure that queued-up code would run when the original context was definitely long-gone. Sure enough, this works as you might expect:

mx3C7D6

I say works as you might expect, but there is a lot going on in the background. The run-time saw that my arbitrary code was referencing arguments that were in the outer scope and via this “closures” technique, it accounted for it.

Bottom line:
This is one of those things that is just a “tool in your toolbox”. It may not have an everyday use, but the one time when you do need it – it’s really the perfect tool for the job!

Posted in Best-practices, Uncategorized
One comment on “Queuing up code to run, and closures in .NET
  1. […] Queuing up code to run, and closures in .NET […]

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 5 other followers

%d bloggers like this: