В този случай, класическата TPL версия използва повече нишки от async/await версията, защото всяко продължение с ContinueWith се изпълнява на различна нишка.
Това се поправя с TaskContinuationsOptions.ExecuteSynchronously:
static Task<TimeSpan> TaskAsyncCalling(TimeSpan time)
{
SleepService.SleepServiceClient client = new SleepService.SleepServiceClient();
return client.SleepAsync(time)
.ContinueWith(t =>
{
TimeSpan result = t.Result;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
return client.SleepAsync(TimeSpan.FromTicks(time.Ticks / 2))
.ContinueWith(t1 =>
{
result += t1.Result;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
(client as IDisposable).Dispose();
return result;
}, TaskContinuationsOptions.ExecuteSynchronously);
}, TaskContinuationsOptions.ExecuteSynchronously)
.Unwrap();
}
От друга страна, продълженията с await обикновено се изпълняват синхронно(ако операцияа завърши на същия синхронизационен контекс, на който е започната или ако няма синхронизация в двете точки на изпълнение). Затова се очаква да придобие с 2 нишки по-малко.
Добро четиво по темата е :
http://blogs.msdn.com/b/pfxteam/archive/2010/05/24/10014209.aspx