Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Feb 24, 2012

Asynchronous Function Looping in C#

It is often the case in code that you have to do several things in a sequence since each computation is dependent on the one(s) before it:
// ...
// stuff 1
// ...
// stuff 2
// ...
// stuff 3
// ... etc.
Good software techniques will tell you that you should break some of these up into methods:

stuff1();
stuff2();
stuff3();
If it gets big, you can even put it all in a collection and iterate (we're starting to get into weird coding now, I don't think anybody would actually do this):
var collection = new List<Action>() { stuff1, stuff2, stuff3 };
foreach (var func in collection){
func();
}
Now the part where this would actually be useful. What if some of these functions could potentially be asynchronous? That is, they depend on some value that may not be readily available - maybe user input, maybe some data from a network, etc. Blocking is not usually a great option - a modal dialog demands that the user pays attention to it even if there is something more important somewhere else. It would be better if this computation could "pause" and then resume later on when we get what we need. In some languages including Scheme and Ruby, you can accomplish this using a construct called callcc:
var collection = new List<Action<Action>>() { stuff1, stuff2,
stuff3 };
foreach (var func in collection){
// pseudo-code warning
call_cc(func);
}
Here, call_cc() will call func and pass in a function which will start executing right after the call_cc() call: it is a continuation of the loop. When func is done (or when it receives the response it wants), it can call this function to nicely continue executing the loop.

Unfortunately, C# 4.0 and lower do not support anything like callcc. C# 5.0 will support the await and async keywords which will accomplish exactly what we want, but for the time being we'll have to make do with what we have. How can we do that without callcc?

Let's give it a shot using a recursive function:
void AsyncForeach(IEnumerator<Action<Action>> iter){
if (iter.MoveNext()){
iter.Current( () => {
AsyncForeach(iter);
});
}
}
void OtherFunc(){
// ...
var collection = new List<Action<Action>>() { stuff1, stuff2,
stuff3 };

AsyncForeach(collection.GetEnumerator());
}
This would require every function in collection adhere to the Action<Action> delegate and when it is done, it will need to call the continuation manually in order to resume the computation. This is a bit annoying, and it's why all the BeginConnect, BeginSend, etc. in System.Net require an AsyncCallback to call when they are done. The new async and await keywords will be extremely useful to accomplish our task since everything is called automatically:
var collection = new List<Action>() { stuff1, stuff2, stuff3 };
foreach (var func in collection){
// func doesn't even need to call anything to
// keep this thing going!
await func();
}
It is useful to learn this from approach though. Say we want to halt the loop prematurely from within one of the functions. In that case, the function could simply not call the continuation. That would end our recursion, causing us to break out of our loop - the equivalent of the break keyword. In order to do that with the await keyword we'd have to have some sort of exception handling system, or return type, etc.

We could go even further and implement something similar to Python's for...else construct where if break is called somewhere in the computation it will run the else block:
for i in range(10):
if i == 5:
break
else:
# this is executed
print "should run"

for i in range(10):
if i == 12:
break
else:
# this is not executed
print "should not run"
We can do this by adding failure "continuations" to our functions:
void AsyncForeach(IEnumerator<Action<Action, Action>> iter,
Action failure){
if (iter.MoveNext()){
iter.Current( () => {
AsyncForeach(iter, failure);
}, failure);
}
}
void OtherFunc(){
// ...
var collection =
new List<Action<Action, Action>>() { stuff1, stuff2, stuff3 };

AsyncForeach(collection.GetEnumerator(), () => {
// handle failure
});
}
In this case the functions stuff1, stuff2, etc. will call the first function if they should continue looping, or call the second one in case of failure.

There's one final tweak to all of this. At the moment there are two problems with AsyncForeach: it depends on the type of the list we're iterating over (IEnumerator<Action<Action, Action>>), and it does not close over any variables that we may need for the loop. Can we do this using a closure?

In fact, we can:
var collection =
new List<Action<Action, Action>>() { stuff1, stuff2, stuff3 };

// declare looper early so that it closes over itself
Action looper = null;
var iter = collection.GetEnumerator();
looper = () => {
if (iter.MoveNext()){
iter.Current(looper, () => {
// handle failure
});
}
};
// don't forget to start the loop
looper();
Since this isn't so DRY, we can top it all off with a function that returns a function:
Action GetAsyncForeach<T>(IEnumerable<T> collection,
Action<T> body){
var iter = collection.GetEnumerator();
return () => {
if (iter.MoveNext()){
body(iter.Current);
}
};
}

void OtherFunc(){
// ...
var collection =
new List<Action<Action, Action>>() { stuff1, stuff2, stuff3 };

Action checker = null;
checker = GetAsyncForeach(collection, (current) => {
current(checker, () => {
// handle failure
});
});
checker(); // start the loop
}
We now have a DRY, re-usable component for implementing an asynchronous foreach loop in our code. It's not the most elegant approach, but it works really well and we don't need that much extra boiler plate to get this done (if C# supported a let rec keyword, we could make it even shorter!).

This is a useful method of looping through some asynchronous tasks that you may have to do. I found myself needing this sort of thing when calling ShowDialog would lock the entire GUI while the system waited for the user to input something, however sometimes the user would have to attend to something else before responding to the dialog. Since later actions in the loop depended on the result of the dialog box, a more asynchronous method was necessary.

Ultimately, this is why I believe that all programmers should have some experience with functional programming; this is a technique that would be obvious to a programmer in Lisp or OCaml but might be a bit trickier to someone who just has OO experience. Having functional programming know-how in your toolbelt will make you a better C# programmer.

Dec 2, 2010

Embedding a Ruby REPL in a .NET App

I've finally gotten fed up with using VB.NET as a scripting language at work, so I decided to try dropping an IronRuby interpreter into the system. It's fairly simple to do, I'll describe here how to build a REPL within your app.

Step 1: Make a window for the REPL. Give it a box for your input and a box for your output. How you do all this is up to you, the interesting part is how to use Ruby within it.

Step 2: Initialize the scripting engine. You need a config file, I call it ironruby.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
   <section name="microsoft.scripting" type="Microsoft.Scripting.Hosting.Configuration.Section, Microsoft.Scripting,
     Version=1.0.0.5000, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
 </configSections>

 <microsoft.scripting>
   <languages>
     <language names="IronRuby;Ruby;rb" extensions=".rb" displayName="IronRuby 1.0" type="IronRuby.Runtime.RubyContext, IronRuby,
       Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   </languages>
 </microsoft.scripting>
</configuration>
You need to make sure you have the DLLs available that IronRuby comes with. Just put them in the same folder as your app.

Now the code to load in your Ruby stuff. Initialize a few objects:
var runtime = new ScriptRuntime(ScriptRuntimeSetup.ReadConfiguration("ironruby.config"));
var engine = runtime.GetEngine("Ruby");

// create a scope - you need to do this in order to preserve variables declared across executions
var globalScope = engine.CreateScope();

// I'm assuming you have a textbox or something named command, just adjust
// this to what you want if you have something else
var result = engine.CreateScriptSourceFromString("(" + command.Text + ").inspect").Execute(globalScope);
And, jackpot! The result variable is a string that is the result of whatever is in the command.Text variable.

This code could be a little bit more robust, so make sure to handle exceptions nicely. An exception will be thrown if say the syntax is invalid, or there are other problems.

The nice thing about this is that you can tinker with the classes within your own application. In the REPL if you put:
# replace MyApp.exe with the .exe or .dll file that your app uses
require "MyApp.exe"
You can then access your namespaces and classes within your own app, and fiddle with them while the app is running!

Nov 16, 2010

Parse vs. TryParse

I was having a problem not too long ago where the performance of a specific bit of code was abysmally slow. I scanned through it to understand theoretically why it might be going slow, and then ran it through a profiler to see where it was spending most of its time. The results were very strange: most of the time was spent parsing strings into integers and decimals (for those who have never done .NET, they have a decimal type in addition to floats and doubles which are better for processing financial data - with decimals, 0.1 + 0.7 actually does equal 0.8). This was very odd, so I figured I'd look at it in more detail.

It turns out that in .NET, the regular Parse() functions throw an exception when the string is not well-formed. If the string is "N/A", then an exception is thrown. This is a common occurrence in the data I was receiving, so I was just catching the exception and setting things to null right away. The problem was that this code was being executed hundreds of times a second, the overhead from exception throwing was adding up!

In high-performance situations, you're better off using a function like TryParse(), which accepts the int/decimal variable as a reference and returns true if the parse was successful. This does not throw an exception and thus is much faster - a massive performance increase was noticed!

While my example here is with .NET, it applies to pretty much any language where a string to int/float method throws an exception when the string is malformed. If your language has something like TryParse, it is definitely recommended over Parse for high-performance situations!

Or an even better moral: don't throw exceptions in code that needs to be fast!

Sep 29, 2010

On C# and .NET

At my current job I've been using C# and VB.NET for development, which are two technologies that I had never used and really shied away from as they are "corporate" technologies. I always figured that C# was just like Java and since I hated Java when I was in university I would have the same reaction when trying out C# for the first time.

Turns out I was wrong. In a nutshell, I would describe C# as "Java done right". The extra features that come with C# are little things that make the language as a whole more pleasant to use, and doesn't make me want to cry when it takes forever to do something simple - as I usually felt when working with Java.

Here's a few of the things I like:
Type Inference - some people will probably hate my code. I use var everywhere. My code looks like Javascript! It's especially useful in foreach loops over dictionaries (aka hashes, I'm so used to using Ruby that I tend to overuse this class):
foreach (var pair in myHash){
  ...
}
This way if my hash has some complicated type I don't need to put KeyValuePair whenever I want to iterate over the collection.

Functional Abstraction - this one is also known as anonymous functions. Check this one out:
CSV.Open("mycsv.csv", "r", row => {
  .. do something to row
});
This is valid C# code! And it works great! It isn't exactly the same as blocks in Ruby (break/next/redo/return don't work the same) but it accomplishes a lot of what I use blocks for.

Events - this is the observer pattern built into the language. I won't go too much into this as you can just learn about it from the Wikipedia page. This is actually something that would be useful in Ruby (probably not that hard to implement as a gem) and is implement in Rails.

There are a number of things that I don't really like - the system is closed and very much owned by Microsoft. While they have their community promise thing going that means they say they won't sue the Mono guys for reimplementing their platform, you never know when they might try to exercise their muscle.

A quick note on Mono: it's great. The executables it produces are binary compatible with Windows, so you can pull the Java-style compile-once-run-everywhere thing - build an executable with Mono in Ubuntu, and it will execute under Windows - provided you're not using any specific libraries. Compile a .dll on Windows with Visual Studio and you can use it just fine in Mono under Ubuntu. I'm impressed.