2

ユーザーにいくつかの関数を作成させるプログラムがあり、ユーザーがすべての関数を作成したら、xミリ秒ごとにそれらを実行します。言い換えれば、私は次のようなものを持っています:

// functionsToExecute is of type = List<Action>
// x = some integer
while(true){

   foreach(Action action in functionsToExecute)
   {
       action();
   }

   Thread.Sleep(x);
}

ここで、関数ごとに待機する時間をユーザーが決定できるようにします。たとえば、ユーザーが 2 つの関数を作成する場合、最初の関数を 500 ミリ秒ごとに実行し、次の関数を 1500 ミリ秒ごとに実行することを希望する場合があります。このシナリオでは 2 つのスレッドを作成し、同じ実装にすることを考えていました。しかし、ユーザーが 50 個の関数を作成した場合はどうなるでしょうか? 50 スレッドが必要になります。

要するに、n ミリ秒ごとに x 個のアクションを実行したいと思います...そのようなアルゴリズムを作成する最良の方法は何ですか? たとえば、3 つのアクションがある場合、最初のアクションを 200 ミリ秒ごとに実行し、次のアクションを 500 ミリ秒ごとに実行し、最後のアクションを 1000 ミリ秒ごとに実行します。

SetTimout多分私はjavascriptの関数に似たものが必要です

4

2 に答える 2

5

.NET 4.5を使用していて、コードがタイムクリティカルでない場合は、タスク並列ライブラリを使用してこれを簡単に行うことができます。

static Task Repeat (List<Action> actions, CancellationToken token, int delay)
{
    var tasks = new List<Task> ();
    var cts = CancellationTokenSource.CreateLinkedTokenSource (token);

    foreach (var action in actions) {
        var task = Task.Factory.StartNew (async () => {
            while (true) {
                cts.Token.ThrowIfCancellationRequested ();
                await Task.Delay (delay, cts.Token).ConfigureAwait (false);
                action ();
            }
        });
        tasks.Add (task);
    }

    return Task.WhenAll (tasks);
}

理想的には、キャンセルを適切にサポートするために、アクションを非同期にする必要もあります。

.NETランタイムは自動的にスレッドのスケジューリングを処理しますが、要求されたタイムアウトの後にアクションが実行される保証はありませ。少なくともその時間が経過し、アイドル状態のスレッドが使用可能になった後に実行されます。

于 2012-12-19T14:19:25.083 に答える
3

ThreadPoolウォークスルー)の使用を検討します。処理する各スレッドを作成し、探しているタイムアウトに基づいて繰り返すようにします。ManualResetEventスレッドを停止する必要がある場合は、 for を保存することもできます。

于 2012-12-19T14:10:18.157 に答える