Thread.Sleepは、タスクを実行しているスレッドをブロックします(これは理想的ではありません)が、多数のタスクを並行して実行していない限り、許容できる妥協案(リスクが低く、パフォーマンスに大きな問題はない)になる可能性があります。 。.NET 4.5には、「async / await」とTask.Delayでいくつかの改善があり、タイマーに基づいて継続を暗黙的に設定します(実行中のスレッドをブロックする必要はありません)が、4.0では直接利用できません。
次のような方法で同じことを自分で行うことができます(あまりテストされていないため、注意して使用してください)。
class Program
{
static void Main(string[] args)
{
var fullAction = RunActionsWithDelay(DoSomething, 2000, DoSomethingElse);
fullAction.Wait();
Console.WriteLine("Done");
Console.ReadLine();
}
static Task RunActionsWithDelay(Action first, int delay, Action second)
{
var delayedCompletion = new TaskCompletionSource<object>();
var task = Task.Factory.StartNew(DoSomething);
task.ContinueWith(t =>
{
if (t.IsFaulted)
{
delayedCompletion.SetException(t.Exception);
}
else
{
Timer timer = null;
timer = new Timer(s =>
{
try
{
DoSomethingElse();
delayedCompletion.SetResult(null);
}
catch (Exception ex)
{
delayedCompletion.SetException(ex);
}
finally
{
timer.Dispose();
}
}, null, delay, Timeout.Infinite);
}
});
return delayedCompletion.Task;
}
static void DoSomething()
{
Console.WriteLine("Something");
}
static void DoSomethingElse()
{
Console.WriteLine("Something Else");
}
}
これはかなり醜いですが、上記よりも少しうまくカプセル化できます。「ハングする」スレッドは排除されますが、継続の設定に関連する追加のパフォーマンスオーバーヘッドがあります。多数の並列タスクを実行していて、それらすべてに遅延を導入する必要がある場合にのみ、これを実行することをお勧めします。