c# - System.Timers.Timer主线程上的Elapsed事件

时间:2014-02-11 19:26:06

标签: c# multithreading events timer

“简单”问题,在控制台应用程序中,如何在主线程中调用System.Timers.Timer Elapsed事件?

我已经阅读了有关SyncronizingObject属性的内容,但是目前我没有尝试实现一个实现ISyncronizeInvoke接口的类。

编辑(澄清):

我正在尝试模拟经典的事件模型。我有一些代码使用基于事件的方法来监视某些设备的状态。问题是某些设备不使用事件发送其状态,并要求应用程序轮询数据。

找到的解决方案是使用计时器并轮询设备。如果检测到任何变化,那么我们将提出现有的类似事件。

问题在于遗留代码远非线程安全,并且适应它将是一项非常艰巨的任务。

也许有更好的方法。

2 个答案:

答案 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