Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 睡眠()与否,如果睡眠()不好,正确的方法是什么?_.net_Multithreading - Fatal编程技术网

.net 睡眠()与否,如果睡眠()不好,正确的方法是什么?

.net 睡眠()与否,如果睡眠()不好,正确的方法是什么?,.net,multithreading,.net,Multithreading,在阅读了这么多的问题并注意到关于生产代码中的Thread.Sleep()有多邪恶的共识后,我决定给出一个在生产代码中使用它的示例,并希望了解如何以其他更好的方式实现我目前使用的Thread.Sleep() 无论如何,我有一些对象正在访问遗留系统(IBM终端)。有时,要在终端屏幕上显示确认消息或完成屏幕导航,甚至需要几秒钟的时间。在我的代码中,我需要检查某个系统消息是否出现在屏幕上,或者是否通过确定终端移动到正确的屏幕或系统返回某个系统消息来完成导航。如果消息不在屏幕上或屏幕未更改,我需要等待几百

在阅读了这么多的问题并注意到关于生产代码中的
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();
}
while(!SysOutput.Contains(successsg)&
OutputWaitCounter
请忽略数据集的东西,这是我必须使用的第三方API的东西


最后,问题很简单,在生产代码的上下文中使用
Thread.Sleep()?如果没有,您将如何解决在尝试从IBM终端获取系统输出之前必须等待几百毫秒的问题?

Thread.Sleep()的问题是它停止该线程上的所有操作。我不会说您永远不应该在生产代码中使用它——这在很大程度上取决于该代码做什么以及如何做

如果这是一个单线程的命令行应用程序,那么老实说,我觉得这没什么大不了的。如果它在这种情况下显著简化了代码,并且没有副作用,那么我建议将其保留


如果这是一个更大的应用程序的一部分,比如说,有其他线程和/或丰富的UI,Sleep()可能会有问题。假设您想发出立即停止该线程的信号,可能是因为有人试图(从另一个线程)关闭该应用程序。您可能不需要等待Sleep()调用完成,而需要使用类似于信号量的东西来向线程发出信号,表示该停止等待、停止线程并清理了。因此,在这种情况下,您可以等待信号量释放(超时)。如果等待信号量的调用超时,您可以像现在一样正常进行。如果信号量真的释放了,在本例中,您将清理线程并优雅地退出。在这种情况下,使用Thread.Sleep()会使其他线程可能需要等待更长的时间才能退出,因为除了等待Sleep()调用之外别无选择。如果你有一个用户界面,并且你正在用户界面线程上执行Sleep(),那么调用Sleep()可能会导致用户界面不稳定或完全没有响应。

你的情况符合我在回答你链接的问题时列出的标准吗?@ChrisShain,我相信是的。。。您觉得呢?我对IBM终端一无所知,所以我没有足够的信息来确定它是否符合这些标准。我也不知道您是否测试了vs.SpinWait(),甚至只是在热循环中调用
HostSession.GetAttributes
。3270类型的终端可能会让您等待很长一段时间,等待结果。使用热循环或SpinWait()可以很好地加热数据中心,因为你要做大量的等待:)@DaveMarkle没错,我看你很熟悉这种痛苦……解决sleep()关机问题的最简单方法是不清理使用它的线程,退出。@Dave Markle这是一个windows服务,与终端交互的每个对象都在它自己的线程上运行…@Martin James:这可能是真的,但在资源管理方面,强行中止线程会对你的应用程序造成一些非常恶劣的影响,尤其是在这种情况下。因为他使用的是终端仿真器,我怀疑他可能在与终端软件进行某种COM互操作,而不清理这些资源可能会导致严重的资源泄漏,这是你真正不希望的@迪安·K:如果你的Sleep()呼叫真的是100毫秒,你可以不受惩罚。但如果他们能等上几秒钟,我想你可能会在从服务控制管理器停止应用程序时遇到一些麻烦。如果要与这些线程进行任何通信,Sleep()也会降低速度。就像我说的,这不一定是你所做的交易的破坏者。如果你所拥有的一切都有效,并且你喜欢它的性能,那么你就不会在将来更新它,让它变得更花哨,我说,离开它吧+1:我同意。除了在UI线程上调用它,我也看不出有什么大不了的。当然,通常有更好的方法,但这取决于你想要实现什么。