Tag Archives: Asynchronous

Tasks – try on retrying, loops, recursions

My mind today was in weird shape (again). I blame Friday. What that means is, that I came with weird pieces of code, that are fun to just write. Brain training. :)

The set up was simple. I had a Task that was returning bool; true if succeeded, false otherwise. Because the code was interacting with 3rd party system it was desired to retry if the call didn’t succeeded.

Looking at it in front of me I realized I’ll be probably able to (ab)use the ContinueWith method and recursion. When I wrote it I realized there’s a room for refactoring. And then I realized I might create and extension method from it. Already half way in hell. :)

public static Task<TResult> Retry<TResult>(this Func<Task<TResult>> taskMethod, Func<TResult, bool> resultOK, int retries)
{
	return taskMethod()
		.ContinueWith(t =>
			retries == 0 || resultOK(t.Result)
				? Task.FromResult(t.Result)
				: Retry(taskMethod, resultOK, --retries))
		.Unwrap();
}

Umm, how it will look like with await, I thought. Then I can use loop.

public static async Task<TResult> Retry2<TResult>(this Func<Task<TResult>> taskMethod, Func<TResult, bool> resultOK, int retries)
{
	while (true)
	{
		var result = await taskMethod();
		if (retries-- == 0 || resultOK(result))
			return result;
	}
}

This doesn’t look nice. I thought it will be smoother. This is like 90s. Back to recursion.

public static async Task<TResult> Retry3<TResult>(this Func<Task<TResult>> taskMethod, Func<TResult, bool> resultOK, int retries)
{
	var result = await taskMethod();
	return retries == 0 || resultOK(result)
		? result
		: await Retry3(taskMethod, resultOK, --retries);
}

That looks better. I don’t know whether I like the first or the third version more. But. What about performance? The second version has least code to execute. No doubt. The third version has two awaits and the recursion (nesting) with awaits. This is probably not going to be good for performance. And my tests confirms that. Slightly slower than second is the first version. Thus the winner for me is version #1. 8-)

I’m not sure why I did this (from practical perspective), but it was fun. Have a great Friday.

Cancel CancellationTokenSource after a timeout

Maybe you already discovered it. But in .NET 4.5 the CancellationTokenSource class has a new method CancelAfter. It allows you to signal cancellation after a specified interval aka timeout.

In .NET 4 you’d have to Wait on a Task to complete or not and if not, do the cancellation. This might go little bit off control if you have a bunch of tasks. In .NET 4.5 a handy Task.Delay was added and with await/async it was easier. But still.

Setting a timeout and basically forgetting about it is a nice little help, that will make the code little more clean and easier to comprehend.

TaskCanceledException on timeout on HttpClient

.NET Framework has a nice new class for all sort of HTTP stuff called HttpClient (interesting the name wasn’t taken before :) ). And because it’s I/O related it has also bunch on XxxAsync methods to nicely fit into C# 5′s async/await.

So you might write code similar to this, based on experience based on previous “network” classes.

var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(200); //adjust based on your network
try
{
	var result = await client.GetStringAsync("http://blog.cincura.net/");
}
catch (HttpRequestException)
{
	// handle somehow
	Console.WriteLine("HttpRequestException");
}
catch (TimeoutException)
{
	// handle somehow
	Console.WriteLine("TimeoutException");
}

If you try to run it, you’ll get unhandled exception, TaskCanceledException to be precise. Yep, the timeout is not propagated as TimeoutException, but as TaskCanceledException. It caught me off guard a little bit. The documentation for Timeout property touches CancellationTokenSource and you can feel the steer to TaskCanceledException. But, still, could be mentioned explicitly, will not be that surprising. Or maybe my thinking was skewed.

This code then works correctly.

var client = new HttpClient();
client.Timeout = TimeSpan.FromMilliseconds(200);
try
{
	var result = await client.GetStringAsync("http://blog.cincura.net/");
}
catch (HttpRequestException)
{
	// handle somehow
	Console.WriteLine("HttpRequestException");
}
//catch (TimeoutException)
//{
//	// handle somehow
//	Console.WriteLine("TimeoutException");
//}
catch (TaskCanceledException)
{
	// handle somehow
	Console.WriteLine("TaskCanceledException");
}

Do not overdo parallelism and asynchronous

Sometimes it’s easy to little bit overdo the need for having everything asynchronous and parallel. Quite often in last few weeks I’ve seen methods similar to this one.

Console.WriteLine("Starting");
Parallel.For(1, 10, async i =>
{
	await Task.Delay(200);
	Console.WriteLine(i);
});
Console.WriteLine("Finished");

What’s the result? For somebody maybe surprisingly:

Starting
Finished

Why? What we see here is a two pieces “process”. First the Parallel.For. This methods runs the provided method in parallel (for our discussion it doesn’t matter how and what exactly that means) and waits for all methods to complete. The lambda expression we’re providing is asynchronous. And though the async/await simplified the programming a lot, it’s still standing on basic principles around Tasks. And that’s the key for understanding what’s wrong. The async lambda is basically (I’m simplifying here) starting a task to do the work and returning that task so you can eventually (a)wait it to complete. But the Parallel.For care about the method (all of them) returning, not (a)waiting tasks (it’s actually an Action<int> also known as “async void” hence it has no idea about the task inside). And here you have it.

The question that’s left is, how to fix it? :) Probably easiest way is to extract the lambda to method and wait for that task to complete. That will make the method blocking so the Parallel.For is not going to end prematurely.

static void Main(string[] args)
{
	Console.WriteLine("Starting");
	Parallel.For(1, 10, i => Action(i).Wait());
	Console.WriteLine("Finished");
}

static async Task Action(int i)
{
	await Task.Delay(200);
	Console.WriteLine(i);
}

But wait. That’s a little bit crazy, isn’t it? We have tasks running asynchronously and we’re spinning Parallel.For and waiting??? You can actually run the loop starting the asynchronous methods capturing the returned tasks and then use Task.WaitAll or if you want to go really deep async ;) you can use Task.WhenAll and await it.

If you’d like to see something like ForEachAsync (or maybe ForAsync) you can get and inspiration and other interesting notes from this Stephen Toub’s blog post.

Unobserved tasks in .NET 4.5

When the Task and other related were introduced, there was behavior that informed you that you are possible doing something wrong. Yes, I’m talking about the exception being thrown from finalizer thread when your task completed as Faulted because of unhandled exception. I think this is absolutely correct behavior. If something as bas as unhandled exception happened I should take care of it no matter what. Because else I might corrupt some data or … what’s worse than corrupt data? ;)

In .NET 4.5 this behavior changed. The async/await brings some interesting considerations. Anyway. The above mentioned behavior was changed. Simply the exception is no longer thrown from finalizer. Good, bad? No matter what, I rather want my application to crash than to run happily next few hours and corrupt more data and do more mess.

Try to run this simple application (outside debugger, with optimization turned on):

Task t = Task.Factory.StartNew(() =>
	{
		Console.WriteLine("Task");
		throw new Exception();
		return 10;
	});
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(1000);
Console.WriteLine("Done");

If you run it under .NET 4.0 you will get something like:

Unhandled Exception: System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.Exception: Exception of type 'System.Exception' was thrown.
   at ...
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.TaskExceptionHolder.Finalize()

Under .NET 4.5 it goes silently to Done. Bummer. If you have some opinion as I, you can luckily revert to the old behavior. Just add to you config into runtime section:

<ThrowUnobservedTaskExceptions enabled="true" />

Back on a safe side. Of course you can still use TaskScheduler.UnobservedTaskException event to be notified about unhandled exceptions from tasks, in case it happens (and it should not in 99,999% cases 8-)), no matter what settings you’re using. It’s just not that punch-me-into-face way with immediate process crash.

Awaiting something in TransactionScope

I like asynchronous programming. The Asynchronous Programming Model and later Tasks with ContinueWith offer great performance especially if no waiting and similar is used.

Although the async/await makes this very simple for 99% of cases, there’s always 1% where you might hit the wall. With callbacks it was little bit obvious, because you wrote the code. Now the compiler is doing the hard work.

If you do something like:

lock (SyncRoot)
{
	await FooBar.DoAsync();
}

You’ll get nice error from compiler saying The 'await' operator cannot be used in the body of a lock statement. And it really makes sense. The lock will very likely provide wrong results under default rewriting work the compiler is doing (and doing it properly for Monitor class needs a lot of knowledge of what you’re trying to achieve. What’s not so clear is that with TransactionScope block (or similar construct) you’re basically doing same stuff, just probably somewhere else in database.

So the compiler is completely OK with:

using (TransactionScope ts = new TransactionScope())
{
	await FooBar.DoAsync();
}

But that’s not what you might had in mind. Consider code like:

static void Main(string[] args)
{
	Test();
}

static async void Test()
{
	Task t = FooAsync();
	Console.WriteLine("Other stuff");
	await t;
}

static async Task FooAsync()
{
	using (Test t = new Test())
	{
		Console.WriteLine("Before");
		await Task.Yield();
		Console.WriteLine("After");
	}
}
class Test : IDisposable
{
	public void Dispose()
	{
		Console.WriteLine("Dispose");
	}
}

The result is correct (and expected, if you look at it closely):

Before
Other stuff
After
Dispose

But considering, that the Other stuff might have some dependency in data being done in that transaction you might get wrong result.

So it’s not always wrong, nor some gotcha in compiler. But think it through before using this construct.