Tag Archives: Multithreading

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.

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.

Asynchronous semaphore

I was just checking some documentation around System.Threading namespace for .NET 4.5 and I found that there’s one nice addition to synchronization primitives.

As you might imaging using async/await with synchronization primitives isn’t particularly good idea, because you can easily make a mistake and end up with code that looks correct but produces completely wrong results.

But still, for some primitives it might be useful. The BCL team (or whoever is responsible to this part) decided, the SemaphoreSlim is worth it. The method is SemaphoreSlim.WaitAsync.

Nice. This might nicely play with some legacy threading code.

Count for System.Collections.Concurrent.ConcurrentStack<T>

Collections in System.Collections.Concurrent namespace are optimized for access from more (basically) threads. That means no stupid “one-lock-for-everything” approach. Actually these are lock free.

It’s good for performance, but also, if used foolhardily, the performance penalty can be too big. One example can be the ConcurrentStack<T> class. As with a lot of collections, this stack also has a Count property. But because it’s a lock free implementation using linked list the Count isn’t that easy. Actually it’s O(n) and this can be especially bad for big stacks. So use with care. As the remarks for this property recommends, if you need to know just whether it’s empty of not, the IsEmpty is better (though realize, that in time you check it it might be empty, but not on next line where you’re about to perform some action and vice versa).

Use the tools, but also know your tools.

Executing method in intervals – good and bad approaches

In last few days I’ve seen couple of pieces of code with “executing method every x seconds”. And a lot of bad. Not buggy, but superfluously expensive. I’m also here adding a simple loop to run just 10 times.

The first bad one is simply using Thread and Sleep method.

void BadOne1()
{
	Thread t = new Thread(o =>
		{
			for (int i = 0; i < 10; i++)
			{
				Console.WriteLine("BadOne1");
				Thread.Sleep(1000);
			}
		});
	t.Start(null);
}

Problem is the Thread object is very expensive and it’s used only fraction of time. The rest is blocked. Simply wasted resources.

I’ve also seen slightly better version.

void BadOne2()
{
	ThreadPool.QueueUserWorkItem(o =>
		{
			for (int i = 0; i < 10; i++)
			{
				Console.WriteLine("BadOne2");
				Thread.Sleep(1000);
			}
		});
}

This is really just a little bit better. ThreadPool thread is used, but again, the thread is doing nothing a lot of time. Again wasted resources.

Better approach is to use Timer. This way you’re not wasting resources by abusing threads. The callback from Timer is executed when the interval is elapsed (on ThreadPool thread). Rest of the time it’s just sits there waiting for next tick.

void GoodOne1()
{
	int i = 0;
	Timer t = null;
	t = new Timer(o =>
		{
			Console.WriteLine("GoodOne1");
			if (Interlocked.Increment(ref i) == 10)
			{
				// could tick, still
				t.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
				t.Dispose(); // or somewhere else
			}
		}, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
}

Here I’d like to point to my older post about keeping the reference to Timer.

And also one question that might come. The Timer ticks every interval no matter how long executing the callback took. That might not be what you want. You may want to execute the method with xx seconds delay between (previous examples), not execute the method every xx second (this example). The solution is pretty easy. Initially just schedule one tick and then reschedule it for next interval.

void GoodOne2()
{
	int i = 0;
	Timer t = null;
	t = new Timer(o =>
		{
			Console.WriteLine("GoodOne2");
			if (Interlocked.Increment(ref i) == 10)
			{
				// could tick, still
				t.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
				t.Dispose(); // or somewhere else
			}
			else
			{
				t.Change(TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan);
			}
		}, null, TimeSpan.Zero, Timeout.InfiniteTimeSpan);
}

All these are kinda low level. But you can use Reactive Extensions (Rx) to write it in more succinct way, but internally the core idea is same as with Timer.

void GoodOne3()
{
	IDisposable obs = null;
	obs = Observable
		.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
		.Take(10)
		.Subscribe(_ =>
			{
				Console.WriteLine("GoodOne3");
			}, () => obs.Dispose() /* or somewhere else */);
}

No matter what approach you’ll use, please don’t (ab)use threads (manually created or ThreadPool ones). Threads are small little nice sweet creatures that don’t deserve to be treated like this. And. Don’t forget to cleanup resources (i.e. Timer is IDisposable).