我们雇用了一家公司,将控制某些工业机械的旧VB6 DLL转换为C#。旧的VB6代码具有“暂停”例程,该例程由撒有DoEvent的睡眠调用组成,因此在睡眠时,仍将处理DLL中的计时器和套接字事件。DoEvent已转换为
System.Windows.Forms.Application.DoEvents();
我不是VB6程序员,但我的理解是VB6实际上是单线程的,因此长时间睡眠会关闭所有内容,包括计时器和套接字事件处理。
当代码转换为C#时,暂停例程如下所示。。。
public static void pauseit_ms(ref int milliseconds)
{
try
{
Sleep(milliseconds / 2);
System.Windows.Forms.Application.DoEvents();
Sleep(milliseconds / 2);
}
catch (Exception exc)
{
LogException("pauseit_ms", exc);
}
}
在.Net中,计时器和套接字事件在各自的线程中运行(在此转换后的代码中,我的大部分工作都是试图使其具有线程安全性!),因此DoEvents()买给我们的东西并不明显。但是MSDN说
调用此方法将导致在处理所有等待窗口消息时挂起当前线程。
那么我们是否应该将这些DoEvents()留在其他事件中(而不是计时器或套接字回调)?还是它们在.Net / C#上下文中是多余的?
DoEvents
创建一个附加的消息循环。这只是一个循环,它读取一条消息,对其进行处理,然后再读取下一条消息,直到获得一条应该停止的消息或没有要处理的消息为止。调用Application.Run
将为您的应用程序创建初始消息循环。在其中一个处理程序中为这些消息创建其他嵌套的消息循环可能会导致各种问题,因此应避免发生这种情况,除非您非常熟悉它的功能以及在什么情况下可以正确使用它。
在大多数情况下,您的程序应该只是异步的,而不是创建附加的消息循环。与其在一段时间内不阻塞当前线程,不如Timer
在一段时间后不阻塞当前线程的情况下使用a之类的方法执行方法。
在.Net中,计时器和套接字事件在各自的线程中运行
实际等待Timer时间过去或等待套接字获得响应的过程完全不使用任何线程。没有线程坐在那里睡觉,而是这些操作本质上是异步的。至于用于执行事件处理程序的线程,将有所不同。有些计时器将使用线程池,有些计时器将使用UI线程,有些则是可配置的,并且两者均可。套接字可能只使用线程池线程。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句