On a recent WPF project, we needed to make long-running service calls in multiple places around the app, so we needed to find a good way to clue in the user about what was going on. What we really wanted to avoid was a lot of code like this:
//do something to set a busy indicator
try
{
//do a bunch of work
}
finally
{
//do something to clean up the busy indicator
}
Too verbose, too repetitive, too error prone. Fortunately, we were soon able to come up with this as a first cut:
protected void DoWork(Action work)
{
//do something to set a busy indicator
try
{
work();
}
finally
{
//do something to clean up the busy indicator
}
}
We were using a MVVM pattern (Prism, specifically), so we dropped this method into our base modules. A controller class, or potentially your base view-models might also make sense, depending on your specific case. We can then call it like this:
DoWork(() => LoadStuff());
Where LoadStuff() is whatever unit of work you're trying to wrap. So how do we actually indicate that work is being done? Well, we found the Mouse.OverrideCursor property to be pretty useful for this. It pretty much does what you'd expect it to, like so:
protected void DoWork(Action work)
{
Mouse.OverrideCursor = Cursors.Wait;
try
{
work();
}
finally
{
Mouse.OverrideCursor = null;
}
}
The only gotcha is that you need to make sure to set it back to null and not something like Cursors.Normal, because otherwise it will override any cursor styles you have set across the app. Now, this works, but it does have one big problem. Namely, it locks the UI, making the entire app unresponsive while work is being done. This wasn't a big problem for us, since our work was all more or less synchronous. But it's not good for a general solution. Something like this is probably more appropriate:
protected void DoWork(Action work)
{
Mouse.OverrideCursor = Cursors.Wait;
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => work();
worker.RunWorkerCompleted += (sender, e) => Mouse.OverrideCursor = null;
worker.RunWorkerAsync();
}
Note that the background worker will swallow exceptions thrown by work, but you can still handle them explicitly in the work completed event. The Error property on the event args holds the exception. There's one more thing we can do that will probably make this a little bit better. It's not too bad to override the mouse cursor here, but it sort of feels like we're mixing UI code into other layers. And if you want some indicator other than the cursor, you risk things getting even uglier. It seems more appropriate to raise events indicating the begin and end of some unit of work. In our app, we were using event aggregation, so we ended up with something like this:
protected void DoWork(Action work)
{
var workEvent = _eventAggregator.GetEvent<WorkEvent>();
workEvent.Publish(WorkEventArg.Begin);
var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => work();
worker.RunWorkerCompleted += (sender, e) => workEvent.Publish(WorkEventArg.End);
worker.RunWorkerAsync();
}
Interested parties can subscribe to those events and alter the UI appropriately.
Hope this helps.
I've spent a lot of time over the past few months learning about functional paradigms and the utility of closures therein. Early in my studies, I came across this hacker kōan:
The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."
Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
-- Anton van Straaten
At the time, I didn't understand quite what it meant. It came up again recently, and with a better understanding, I think I'm beginning to understand what they mean. First, a little background. If you're not familiar with closures, here's the short version: closures are functions, but they're also a set of variable bindings based on the scope they were defined in. For instance, we can define a function like this:
int number = 5;
Func<int> closure = () => number;
Notice that the lambda we return takes no parameters, but it is still able to make reference to number. We say the lambda has "closed over" the variable, creating a closure. Note that the lambda has a reference to the actual variable in question instead of just taking a snapshot of the variable in time. For example, here's the classic "gotcha":
var closures = new List<Func<int>>();
for (int i = 0; i < 10; i++)
closures.Add(() => i);
foreach (var closure in closures)
Console.WriteLine(closure());
What would you expect this to output? It seems straightforward, but remember that each closure refers directly to i, so we see this result:
We can avoid the problem like this:
for (int i = 0; i < 10; i++)
{
int number = i;
closures.Add(() => number);
}
This produces the result we actually wanted:
Ok, hopefully we now have a decent understanding of what closures are and how they work. Closures are a powerful tool when used correctly, but they do require some care.
Now, what does this have to do with objects? Objects are a familiar concept to most, but they mean different things to different people. Most languages support their own particular flavor of object-oriented programming, and you pretty much work with what they give you. One concept common to most is encapsulation, the idea of private state inaccessible to other objects. Note that we get this for free with closures: when a closure outlives the scope it's defined in (say, as a return value from a function), no one can touch the variables that have fallen out of scope. Like so:
public static Func<int> CreateClosure()
{
int number = 5;
Func<int> closure = () => number;
return closure;
}
When we invoke this function, we get the closure back. number has fallen out of scope, but it persists because our closure has closed over it. In effect, number is private state in our closure. That's kind of cool, but what we really need to make this interesting is some form of method dispatch. This is another common construct in OOP: the idea that objects expose some interface for controlled interactions with private state. Since our object is a function, we only have one point of entry. But if we make that entry point a function that dispatches functions based on messages passed in, we can do some interesting things. Let's see if we can hack something together:
public static Func<string, string> CreateClosure
(Dictionary<string, Func<string[], string>> methods)
{
return message =>
{
string[] methodWithParams = message.Split(new[] { ' ' });
string methodName = methodWithParams[0];
string[] withParams = methodWithParams.Skip(1).ToArray();
if (!methods.ContainsKey(methodName))
return "message not understood!";
return methods[methodName](withParams);
};
}
The string manipulation code is a pretty ugly, but the premise is simple. First, we accept a dictionary of methods as a parameter. This will hold the public functions that our closure will respond to. Then we define and return our actual closure. This is just a function that receives a message as a string and dispatches the appropriate function. For a trivial (but instructive!) example, we'll use this pattern to create a representation of a pez dispenser.
Let's add some private state and a few methods:
public static Func<string, string> PezDispenserInit(string name)
{
int count = 0;
var methods = new Dictionary<string, Func<string[], string>>();
methods["describe"] = parameters =>
{
return string.Format("my favorite {0} pez dispenser - it has {1} pez left", name, count);
};
methods["dispense"] = parameters =>
{
if (count > 0)
{
count--;
return string.Format("a delicious pez! {0} has {1} pez left", name, count);
}
else
{
return string.Format("{0} is out of pez . . .", name);
}
};
methods["add"] = parameters =>
{
int add = int.Parse(parameters[0]);
count += add;
return string.Format("added {0} to {1}! now {1} has {2} pez!", add, name, count);
};
return CreateClosure(methods);
}
We've added private data (name and count) and a few methods to call based on messages. Note that each of our public methods is also a closure; the public methods close over our private state, and our method dispatcher closes over the dictionary of methods. To keep things simple, I've adopted the convention that each method takes an array of strings as a parameter and returns a string. The methods themselves are all pretty self-explanatory, so I won't go into detail. Now, let's add a little code to create a simple command line interpreter:
static void Main(string[] args)
{
var closures = new Dictionary<string, Func<string, string>>();
while (true)
{
Console.Write("> ");
string[] line = Console.ReadLine().Split(new[] { '.' });
string name = line[0];
string message = line[1];
string result;
if (message == "init")
{
closures[name] = PezDispenserInit(name);
result = name + " initialized";
}
else
{
result = closures[name](message);
}
Console.WriteLine(result);
}
}
We have a dictionary for our closure objects allowing us to specify them by name and pass a message. We handle the init message explicitly to create new closures. Kind of a kludge, but this is just an example. Otherwise, we just forward messages onto the appropriate closures. Let's try it out:
Pretty cool. Notice that each object maintains its own internal state separate from the other. But is this really useful? All we've really gained is stuff that's built into C#'s type system. What it really gives us is total flexibility. For example, C#'s type system is designed for class-based inheritance (as are many mainstream languages). This is useful in some domains (UI programming, for example), but I don't think it's a great fit in a lot of scenarios. If I wanted to use prototypal inheritance (Steve Yegge has written extensively about this) instead, I'm sort of out of luck. But if I can define my own object system via closures, it's actually pretty simple (look for a future blog post on this).
To close, let's go back to the original point. Objects are a poor man's closures: closures give you complete flexibility to suit your solution to the domain. But the reverse is also true; closures are a poor man's objects. Objects have a slew of advantages over closures because the language (whatever language you're using) is built with its own type system in mind. Even if it's not an ideal model for the problem, the out-of-the-box solution is almost always going to be the correct one for reasons of readability, maintainability, performance, etc. So keep these techniques in mind, but use them very sparingly.
Hope this helps.
A coworker suggested that my last post would be a lot easier to visualize if it had . . . well, visuals. So I thought I'd revisit it and add some pretty pictures. This post will be pretty to-the-point and light on actual details, since we covered them last time. First, we're going to change around some of the methods in our random generator class:
private static readonly Rect Screen =
new Rect(new Point(0.0, 0.0), new Point(300.0, 300.0));
public static IEnumerable<Point> GetRandomOnscreenPoints()
{
foreach (var point in GetRandomPoints(Screen))
{
yield return point;
}
}
This is simply a method to get a bunch of random points on the "screen," which we've arbitrarily defined to be 300x300. Next, we need to filter these values. We'll filter out everything but those points lying on the "border" of the screen:
private static readonly Rect Border =
new Rect(new Point(10.0, 10.0), new Point(290.0, 290.0));
public static IEnumerable<Point> GetRandomBorderPoints()
{
foreach (var point in GetRandomOnscreenPoints()
.Where(p => !Border.Contains(p)))
{
yield return point;
}
}
Now, we need a way to visualize this data. We'll build a simple WPF app with a window:
<Window x:Class="RandomPointFilteringTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Random Point Filtering" SizeToContent="WidthAndHeight">
<Canvas x:Name="canvas" Height="300" Width="300"/>
</Window>
The window will call our code in its constructor, like so:
foreach (var point in RandomGenerator.GetRandomBorderPoints().Take(2000))
{
var dot = new Ellipse
{
Fill = Brushes.Blue,
Height = 2.0,
Width = 2.0
};
Canvas.SetLeft(dot, point.X);
Canvas.SetTop(dot, point.Y);
canvas.Children.Add(dot);
}
Which yields a frame of little dots around the edge of our window:
Nice! To show off the versatility of this pattern, we'll quickly add another method for filtering. This one will filter for points in the corners of the window:
private static readonly Rect HorizontalDivider =
new Rect(new Point(0.0, 100.0), new Point(300.0, 200.0));
private static readonly Rect VerticalDivider =
new Rect(new Point(100.0, 0.0), new Point(200.0, 300.0));
public static IEnumerable<Point> GetRandomCornerPoints()
{
foreach (var point in GetRandomOnscreenPoints()
.Where(p => !HorizontalDivider.Contains(p))
.Where(p => !VerticalDivider.Contains(p)))
{
yield return point;
}
}
And we call it like so:
foreach (var point in RandomGenerator.GetRandomCornerPoints().Take(5000))
{
var dot = new Ellipse
{
Fill = Brushes.Blue,
Height = 2.0,
Width = 2.0
};
Canvas.SetLeft(dot, point.X);
Canvas.SetTop(dot, point.Y);
canvas.Children.Add(dot);
}
This yields a nice "cross" pattern:
Cool.