A very common scenario when you scatter and gather, i.e. start a number or parallell tasks and then wait for them all, is that you really just want to wait for all if they all succeed. in the case there is an error you typically want to wait no more, handle the error, cancel any tasks not already completed and then move on. Here are a few extension methods I would use in this case:
1: public static Task WhenAllOrError(params Task tasks)
3: return WhenAllOrError(new Progress<int>(), tasks);
6: public static Task<T> WhenAllOrError<T>(params Task<T> tasks)
8: return WhenAllOrError(new Progress<T>(), tasks);
11: public static Task WhenAllOrError(
12: IProgress<int> progress,
13: params Task tasks)
15: var errorResult = new TaskCompletionSource<bool>();
16: int completed = 0;
17: foreach (var task in tasks)
20: t =>
22: progress.Report(Interlocked.Increment(ref completed));
23: if (t.IsCanceled)
27: else if (t.IsFaulted)
35: return Task.WhenAny(errorResult.Task, Task.WhenAll(tasks)).Unwrap();
38: public async static Task<T> WhenAllOrError<T>(
39: IProgress<T> progress,
40: params Task<T> tasks)
42: var errorResult = new TaskCompletionSource<T>();
43: foreach (var task in tasks)
46: t =>
48: if (t.IsCanceled)
52: else if (t.IsFaulted)
60: return t.Result;
63: return default(T);
67: return await await Task.WhenAny(errorResult.Task, Task.WhenAll(tasks));
Naturally there is a little code duplication between the Task and the Task<T> versions but starting new tasks just to make a Task into a Task<T> does not feel motivated here I think.
if you're working with a Task based API that does not follow the TAP rules and hence does not expose an option to cancel you can always add your own this way:
1: public static Task<T> WithCancellation<T>(
2: this Task<T> task,
3: CancellationToken cancellationToken)
5: var taskCompletionSource = new TaskCompletionSource<T>();
6: var cancellationRegistration = cancellationToken.Register(
7: () => taskCompletionSource.TrySetCanceled());
9: t =>
12: if (t.IsCanceled)
16: else if (t.IsFaulted)
26: return taskCompletionSource.Task;
This naturally will not actually stop the task you wrap this way but at least it returns control to the code waiting for completion faster.
The same way we in CCR sometimes wanted to add a timeout to an existing "task" you probably want to do the same in TAP. So here are two extension methods you could use to add a timeout to any task of your choice:
1: public async static Task WithTimeout(this Task task, TimeSpan timeout)
3: var cancelationSource = new CancellationTokenSource();
4: var delay = Task.Delay(timeout, cancelationSource.Token);
5: await Task.WhenAny(task, delay);
6: if (task.IsCompleted)
12: throw new TimeoutException();
16: public async static Task<T> WithTimeout<T>(this Task<T> task, TimeSpan timeout)
18: await ((Task)task).WithTimeout(timeout);
19: return await task;
With .Net 4.5 and async/await we have yet another pattern for asynchronous programming and it's time for you to really embrace this. The pattern is called Task-based Asynchronous Pattern, or TAP for short. in my opinion a good asynchronous pattern makes asynchronous code look synchronous. i think it's something with our brains that just have a hard time grasping asynchronously in a good way. But We have to wait and see if there will be a downside with TAP because a pattern that hides something too well might also cause problems, especially when it comes to edge cases.
Anyway, what is TAP? Well you use tasks and in my opinion you typically avoid using the ContinueWith method. The use of ContinueWith will probably be more to optimize than make the code easy to understand. Apart from that (my own observation) a TAP method follow the following rules:
Over the next few days I'll give you some nifty task combinators you might want to use.
Remember the Netflix Chaos Monkey? Last week they released the source code for it. maybe we'll see a port to .Net and Azure on codeplex soon?
I recently did some work using the VS 2012 RC together with R# 7. I needed to use the shim functionality from Fakes but ran into trouble. My unit test failed with a ShimNotSupportedException. After a little bit of searching I realized it was because I was using the R# unit test runner (since it's much faster and report failures in a much better way than the built in runner (if you ask me). Because if I ran the tests using the VS runner the tests passed. Annoying and I can only hope this is going to be resolved by jetBrains but meanwhile I'll be using the following work around:
This way my tests using Shims are ignored by the R# unit test runner. You might think this is a bad idea and generally it is. However I use Shims rarely so there are relatively few tests that are ignored this way. So while working on things that do not require Shimming I can continue to use the fast R# test runner. And when I need to use Shims I just use the VS runner. Not perfect but a decent compromise for me in this case.
When I think of robots I think about autonomous robots. Robots that move around on their own and that do not need interaction with other devices to function. This is a very hard problem to solve but impressive when done well. More commonly robots are remote controlled and may even have sensors around the environment in order to function. Here is a fun video of such a "robot":
If you want to see some other videos of great usages for autonomous robots in your home you should look here. And if you just want a long discussion on what a robot for the home could be I definitely recommend you read this.
A Swedish friend who just had twins here in the US asked me about the passport troubles we had with my daughter (who is also born in the US) so that they could avoid it. It's quite a fun story so here it is.
First a little background; in Sweden everybody gets a "personal number" (kind of like social security here in the US). It consist of your birth date (YYMMDD) followed by 4 digits here the third digit indicates sex (odd=male, even=female) and the last digit is a check-sum digit calculated from the other 9 digits using a simple algorithm.
When my daughter was born we registered her with the Swedish authorities through the consulate so that she would be a Swedish citizen. Since my daughter never actually never lived in Sweden she did not get a personal number but a coordination number (same format and algorithm except the birth date have a number added to it).
On her first trip to Sweden she traveled on her US passport but we thought it would ba good to have a Swedish passport for her too so we went to a police station to get her passport. But they couldn't do anything because the person with our doughter's coordination number did not have any parents according to the computer. When they looked at me and my wife we did have a daughter with the same name, but the personal number listed was our daughter's birth date followed by four zeros (which is never a valid personal number). Hence she couldn't get a passport.
I went back to the Swedish IRS (who owns the personal number registry) and they just sighed... Apparently this happens a lot to people having kids while living abroad; the consulates add the correct information into one system, but not two as they should. They could however provide me with screen shots from their system that kind of proved we were parents to our daughter but I could just have made those myself... Back at the police station we finally got our daughter's passport using these screen shots as proof of parenthood...
Next time we are in Sweden we can resolve this situation by bringing our daughter to the IRS and show them in person she exists. Until we do that they do not update the database so as far as that goes my daughter have no parents.
The thing that really intrigues me is that Sweden is a country with about nine million people. Even given a certain history there should be no problem to keep this in a single database. So no need to go all NoSQL and have non-normalized data. It would make perfect sense to have this data normalized and I think parent-child relations is a pretty obvious example form any text book on database design. But no, apparently that is not the case because that would have been too easy I guess.
I co-worker of mine stumbled over a nice collection of helpful information when working with threads in C#. Once you start using .net 4.5 with its async/await patterns you might be using multi-threading more than before and it's good to understand the basics.
I recently saw this post with ten tips on how to be a better developer. It made me think of the Viking Laws again. The Viking Laws covers a few more aspects than the Ten Commandments which essentially just tell you to be a good person and point out a few different aspects of being a good person. So I think the title should really be Ten Commandments for Teams since I think the advice is applicable to any group of individuals working together towards a goal.