当你运行一段代码比处理该块中的代码更快时会发生什么?

时间:2017-05-30 10:01:08

标签: c#

假设您有一个每100毫秒运行一次的代码块,但该块中的代码需要500毫秒才能运行。它是否完成了代码块的处理?

while (true)
{
    System.Threading.Thread.Sleep(100);
    OnTick();
}

public void OnTick(){ //Block of code that take 500 milliseconds to process }

6 个答案:

答案 0 :(得分:7)

此代码不会每100毫秒运行一次,它会在每次迭代之间等待100毫秒。重要的区别。

您正在同步调用该代码,因此该循环的下一次迭代将在OnTick()返回后发生。

现在,如果这是一个实际的计时器滴答(而不是Thread.Sleep()),或者500毫秒的工作将在另一个线程上发生,这将会改变。

答案 1 :(得分:6)

你的循环每100毫秒不会运行500毫秒的代码块;它运行500毫秒的块,它们之间的延迟为100毫秒。每次迭代需要600毫秒:

SleepRun

您可以制作一段代码,每100毫秒启动一个新的代码块。如果代码占用500毫秒的CPU时间,则只要可用内核数量耗尽,系统就会过载。

另一方面,如果500毫秒块中的代码花费大部分时间在单独的线程中休眠或等待I / O,则系统将继续生成新线程,直到达到最大值,或者记忆力已经耗尽。

答案 2 :(得分:3)

这完全取决于OnTick()的实现 - 如果它是同步的,并且不产生任何后台线程(等),那么你的循环将等待100ms,花费500ms运行OnTick(),然后(并且只有这样)等待另一个100ms,然后再次运行OnTick()

答案 3 :(得分:0)

与大多数其他编程语言一样,C#使用顺序执行。

这意味着执行一个语句,然后执行下一个语句。

这意味着在您的示例中,代码等待100毫秒,然后它执行500毫秒的操作。

答案 4 :(得分:0)

while循环等待100毫秒,然后调用onTick()。因此,下一次迭代将在onTick()返回后发生。它是顺序的。

答案 5 :(得分:0)

正如其他人已经解释的那样,你的代码只是在另一个之后执行一个语句。

我认为实际的问题是如何在没有重叠执行的情况下每100毫秒运行一次。否则,您可以直接使用System.Threading.Timer

一种选择是使用Task.Delay在循环内异步等待100ms。

public async Task RunTimer(Action act,TimeSpan delay,CancellationToken token)
{
    while(!token.IsCancellationRequested)
    {
        await Task.Delay(delay,token);
        if (!token.IsCancellationRequested)
        {
            act();
        }
    }   
}

取消令牌允许取消计时器。例如:

var cts=new CancellationTokenSource();
var delay=TimeSpan.FromMilliseconds(100);
var timerTask= RunTimer(()=>someMethod(),delay,cts.Token);
...
cts.Cancel();