“简单”问题,在控制台应用程序中,如何在主线程中调用System.Timers.Timer
Elapsed事件?
我已经阅读了有关SyncronizingObject
属性的内容,但是目前我没有尝试实现一个实现ISyncronizeInvoke
接口的类。
编辑(澄清):
我正在尝试模拟经典的事件模型。我有一些代码使用基于事件的方法来监视某些设备的状态。问题是某些设备不使用事件发送其状态,并要求应用程序轮询数据。
找到的解决方案是使用计时器并轮询设备。如果检测到任何变化,那么我们将提出现有的类似事件。
问题在于遗留代码远非线程安全,并且适应它将是一项非常艰巨的任务。
也许有更好的方法。
答案 0 :(得分:3)
您的主线程需要首先具有某种消息循环,以及向该消息循环发送消息的机制。如果您在桌面UI环境中,例如winforms,WPF等,这将为您创建,但由于您不是,您需要自己创建一个。
一个消息循环,在它最主要的层面,看起来像这样:
while(!ShouldApplicationExit())
{
var nextMesage = someQueueOfMessages.Dequeue();
nextMessage();
}
当然,您需要为人们提供一些方法来向该队列添加消息,并且可能某种方式指示应用程序应该在某个时刻退出。如果没有物品,你的队列也应该阻止,而不是崩溃和燃烧。
如果你愿意,你可以自己做所有这些。除非它需要特别花哨,否则不是那么费时。
其他选项是使用其他东西来创建消息循环,例如Application.Run
,它将在内部有一个看起来有点像我所展示的那样的循环。
一旦您创建或决定了消息泵的实现,您就会得到一些向泵添加新消息的机制。这就是你在ISyncronizeInvoke
实现中需要做的事情,呼唤那个机制。
答案 1 :(得分:0)
System.Timers.Timer
来触发事件。
如果您需要在具有更多控制权的控制台应用程序中进行定时回调,您可以CreateThread
您自己的其他线程,拥有此WaitForSingleObject
并让事件在运行时中断前台任务
有关类似的讨论,请参阅.Net Timeouts: WaitForSingleObject vs Timer。