在阅读this SO问题并注意到关于生产代码中有多么邪恶Thread.Sleep()
的共识后,我决定举例说明我在生产代码中使用它的位置,并希望了解如何实现我目前使用的Thread.Sleep()
用于其他更好的方式......
无论如何,我有对象正在访问遗留系统(IBM终端)。有时甚至可能需要几秒钟才能在终端屏幕上显示确认消息或完成屏幕导航。在我的代码中,我需要检查屏幕上是否出现某个系统消息,或者是否通过确定终端移动到正确的屏幕或者系统返回了某个系统消息来完成导航。如果消息不在屏幕上或者屏幕没有改变,我需要等待几百毫秒并尝试再次从屏幕上获取确认字符串,并继续这样做,直到预期的消息在屏幕上或预定义的操作超时到达了。
代码看起来像这样:
while (!SysOutput.Contains(successMsg) &&
OutputWaitCounter < WaitTime * Settings.Default.WaitTimeMultiplier)
{
Thread.Sleep(Settings.Default.ThreadSleepTime);
OutputWaitCounter++;
DsGetAttributes = HostSession.GetAttributes(GetAttributes);
SysOutput = DsGetAttributes.Tables[0].Rows[0][0].ToString();
}
请忽略DataSet的东西,这是我必须使用的第三方API ...
最后,问题很简单,在生产代码的上下文中使用Thread.Sleep()
是否可以?如果没有,您将如何解决在尝试从IBM终端获取系统输出之前必须等待几百毫秒的问题?
答案 0 :(得分:2)
Thread.Sleep()的问题在于它会停止该线程上的所有。我不会说你应该永远在生产代码中使用它 - 它在很大程度上取决于代码的作用以及它是如何做的。
如果这是一个进行这些调用的单线程命令行应用程序,老实说,我没有看到它的大不了。如果它在这种情况下显着简化你的代码没有副作用,我说保留它。
如果这是更大的应用程序的一部分,例如,使用其他线程和/或丰富的UI,Sleep()可能会有问题。假设您想要立即停止此线程,可能是因为有人试图关闭应用程序(从另一个线程)。你不必等待Sleep()调用完成,你可能想要使用像Semaphore这样的东西向你的线程发出信号,告诉它是时候停止等待,停止线程并清理。因此,在这种情况下,您可能会等待信号量释放(超时)。如果等待信号量的呼叫超时,你就会像往常一样正常进行。如果信号量实际释放,在这种情况下,您将清理线程并优雅地退出。使用Thread.Sleep()使得在这种情况下你的其他线程可能需要等待更长时间才能退出,因为除了等待Sleep()调用之外别无选择。如果你有一个用户界面并且你在你的UI线程上睡觉(),调用Sleep()可能会导致一个不稳定或完全没有响应的用户界面。