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 毫秒运行一次。我正在考虑为这种情况创建两个线程,然后具有相同的实现。但是如果用户创建了 50 个函数呢?我需要50个线程!

简而言之,我想每 n 毫秒执行 x 次动作……创建这种算法的最佳方法是什么?例如,如果我有 3 个动作,我希望每 200 毫秒执行第一个动作,每 500 毫秒执行下一个动作,每 1000 毫秒执行最后一个动作。

也许我需要类似于SetTimoutjavascript 中的函数的东西

4

2 回答 2

5

如果您使用的是 .NET 4.5 并且您的代码对时间要求不高,那么您可以使用 Task Parallel Library 轻松做到这一点:

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);
}

Ideally, you should also make your actions async to properly support cancellation.

The .NET runtime automatically takes care of thread scheduling, but there's no guarantee that your action will be executed after exactly the requested timeout. It will be executed after at least that time has elapsed and there's an idle thread available.

于 2012-12-19T14:19:25.083 回答
3

我会考虑使用ThreadPool演练)。创建每个要处理的线程,并根据他们正在寻找的超时重复它。ManualResetEvent当您需要线程停止时,您还可以存储for 。

于 2012-12-19T14:10:18.157 回答