July 05, 2014

More Async and Await

Saw an article about async programming in other languages. There is a big difference between parallel and concurrent programming that is hard to see sometimes. This post is just to outline it more.

The other languages that I was reading about was node.js vs GO. The idea was that node’s main issue is error control with async programming. While I find that it is an issue, the author said that GO was awesomer at async programming, which is different from concurrence. This is what I was talking about in previous articles with erlang and F#’s way they make things async.

Anyways, I was trying to come up with examples of how to show the async and parellel models. This way it would show the difference. Let’s take this example:

 public void PrintNumbersAsync() { int start = 1; for (int i = 0; i < 10000; i++) { var func = new Func<object, Task>(async (value) => { return (int)value + 1; }); var task = func.Invoke (start); task.Wait (); start = task.Result; } Console.WriteLine ("Async: {0}", start); } public void PrintNumberTask() { int start = 1; for (int i = 0; i < 10000; i++) { var func = Task.Factory.StartNew((value) => { return (int)value + 1; }, start); func.Wait (); start = func.Result; } Console.WriteLine ("Task: {0}", start); } </pre> 

The example shows 2 functions, one using async and one using Task. If you run these functions you get these results:

 Async: 10001 Async time: 66 Task: 10001 Task time: 294 

The reason that async wins in this scenario is because async is actually running synchronous. And because of that, it does not have to wait for threads or other heavy operations that the Task function has to do. Now, let’s do a simple change to the code with a small delay:

 public void PrintNumbersAsync() { int start = 1; for (int i = 0; i < 10000; i++) { var func = new Func<object, Task>(async (value) => { await Task.Delay(1); return (int)value + 1; }); var task = func.Invoke (start); task.Wait (); start = task.Result; } Console.WriteLine ("Async: {0}", start); } public void PrintNumberTask() { int start = 1; for (int i = 0; i < 10000; i++) { var func = Task.Factory.StartNew((value) => { Task.Delay(1); return (int)value + 1; }, start); func.Wait (); start = func.Result; } Console.WriteLine ("Task: {0}", start); } </pre> 

We are adding a Task.Delay in the Func to cause the async and task to delay slightly. Here are the results:

 Async: 10001 Async time: 10648 Task: 10001 Task time: 390 

Weird, now Async is all slow, but Task is about the same speed. This is because async IS SYNCHRONOUS. This means it runs on the same thread, and waits for each item in the for loop because of the delay. The difference is subtle, while the async is slower, it is not blocking the same thread. In the task code, it is blocking on each call. If you have calculations, Task would be better, IO calls, then async would be better.

If I missed something let me know.