重複の可能性:
c# でタスクの開始を遅らせる正しい方法は何ですか?
将来実行される小さなタスクをスケジュールする必要があります (遅延は常に 1 分未満です)。実装は、.NET 4.0 ランタイムの .NET で行われます。Async ctp はオプションですが、今のところ付加価値はありません。
- スケジューリングは非同期である必要があります
- スケジューリングの解決は秒単位です
- タスクの実行は暗黙的に非同期です(私は思います)
- スケジュールされたタスクの数は数百または数千になる可能性があります
- 可能性は低いですが、2 つのタスクがまったく同時にスケジュールされる可能性があります。
私の現在の解決策はこれです:
internal class TimerState
{
internal Timer Timer { get; set; }
internal object Payload { get; set; }
internal Action<object> Action { get; set; }
}
public class TimerModule
{
public static void ScheduleTask(object input, Action<object> action, TimeSpan delay)
{
//create state to pass to timer method
var state = new TimerState { Payload = input, Action = action };
//schedule timer without firing
var t = new Timer(HandleScheduleTimer, state, -1, -1);
//add timer to state to be able to dispose it
state.Timer = t;
//schedule timer to fire in delay time
t.Change(delay, TimeSpan.FromMilliseconds(-1));
}
private static void HandleScheduleTimer(object state)
{
var s = state as TimerState;
Task.Factory.StartNew(s.Action, s.Payload, CancellationToken.None,
TaskCreationOptions.PreferFairness, TaskScheduler.Current);
//dispose the timer immediately
if(s.Timer != null)
s.Timer.Dispose();
}
}
パフォーマンス カウンター (.NET 物理スレッド) を使用していくつかのテストを行いましたが、ほぼ同時に数千のタスクをスケジュールしているにもかかわらず、同時に実行されているスレッドは多くありません。
これを行うより良い方法はありますか?
これに関する実証済みの設計パターンはありますか?
ほとんどの場合、再起動後もスケジューリングが信頼できることがわかりましたが、それは必要ありません。クラッシュ後にシステム内のデータを再生し、実行されなかったスケジュールされたタスクを補うことができます。
編集:何千ものスレッドが同時に実行されるのを見たいという意味ではありません。これはおそらくスレッドプールで処理されることを認識しています。コメントで述べたように、100 秒以上にわたる 5M タスクのテストでは、物理スレッドで 20 の増加しか見られません。
私の主な質問はこれです: タスクの実行を遅らせるより良い方法はありますか?