4

我正在编写一个应用程序,它通过一个复杂的 API 与一个又大又丑的第 3 方系统一起工作。有时系统中会发生一些错误,但如果我们等待我的程序面对这些错误,可能为时已晚。

因此,我使用一个单独的线程来检查系统状态,如下所示:

while (true)
{
    ask_state();
    check_state();
    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
}

如果我每 100 毫秒或每分钟检查一次系统状态并不重要。

但我听说使用 Thread.Sleep() 是一种不好的做法。为什么?在这种情况下我能做什么?

4

3 回答 3

5

一个原因是Thread.Sleep()阻止你的代码做任何其他事情。最近的努力是尽可能减少阻塞。例如,node.js 是一种非阻塞语言。

更新:我不知道TimerC# 中类的基础结构。也许它也在阻塞。

您可以安排一个任务每 100 毫秒检查一次第三个 API。这样,在这 100 毫秒内,您的程序可以执行其他任务。

更新:这个类比可能会有所帮助。如果我们将操作系统与医院进行比较,并将线程与该医院的护士进行比较,主管(程序员)可以选择一个策略:

  1. 要么让每个护士(线程)看一个,而且只看一个病人(一项工作,一项要完成的任务),即使在每次检查之间她等待一个小时(Sleep()方法)
  2. 要求每个护士检查每个病人,并在直到下一次检查的时间间隔内,继续检查其他病人。

第一个模型是阻塞的。它不可扩展。但是在第二种模式中,即使护士很少,你也可以服务很多病人。

于 2013-11-15T07:45:50.970 回答
3

因为如果它在内部等待,关闭该线程的唯一方法Sleep是 a) 等待Sleepto 结束,或 b) 使用Thread.Abortor之一Thread.Interrupt1

如果是长时间的睡眠,那么 (a) 并不适合您想要做出响应。并且 (b) 如果代码恰好不在当时实际上是非常令人讨厌的Sleep

如果您希望能够以合适的方式中断睡眠行为,那么使用可等待对象(例如 a ManualResetEvent)会更好 - 您甚至可以将可等待对象的等待放入while条件中,明确什么会导致线程退出。


1我在这种情况下使用了shutdown,因为这是需要跨线程通信的非常常见的场景。但是对于任何其他跨线程信号或通信,同样的论点也可以应用,如果它没有关闭,那么Thread.Abort甚至Thread.Interrupt更不适合。

于 2013-11-15T08:11:35.247 回答
0

我会为你想要的任何毫秒设置一个计时器,然后等待我的检查方法完成,顺便说一句,你想使用一个永恒的循环还是你在那里显示的不是一个完整的代码?
好的,这是我正在谈论的示例:

public void myFunction()
{
int startCount = Environment.TickCount;
ask_state();
check_state();

while (true)
{
if (Environment.TickCount - startCount >= 20000) //two seconds 
{
break;
}
Application.DoEvents();
}
}

//Now you have an organized function that makes the task you want just call it every
// time interval, again you can use a timer to do that for you

private void timer_Tick(object sender, EventArgs e)
{
            myFunction();
}

祝你好运

于 2013-11-15T07:50:06.193 回答