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



"简单"问题,在控制台应用程序中,我们如何在主线程中调用System.Timers.TimerElapsed事件?

我读过一些关于SyncronizingObject属性的内容,但目前我还没有成功地尝试实现一个实现ISyncronizeInvoke接口的类。

编辑(澄清):

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

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

问题是遗留代码远不是线程安全的,对其进行调整将是一项艰巨的任务。

也许还有更好的方法。

您的主线程首先需要有某种类型的消息循环,以及向该消息循环发送消息的机制。如果你在桌面UI环境中,比如winforms、WPF等,这将是为你创建的,但由于你不是,你需要自己创建一个。

在最初级的层次上,消息循环看起来像这样:

while(!ShouldApplicationExit())
{
var nextMesage = someQueueOfMessages.Dequeue();
nextMessage();
}

当然,您需要公开一些方式,让人们向队列中添加消息,并可能以某种方式指示应用程序应该在某个时刻退出。如果没有项目,队列也应该阻塞,而不是崩溃和烧录。

如果你愿意,你可以自己做这一切。除非它需要特别花哨,否则它并不那么耗时。

其他选项是使用其他东西来创建消息循环,例如Application.Run,它将在内部有一个循环,看起来有点像我在引擎盖下显示的。

一旦您创建或决定了消息泵的实现,您就可以使用它向泵添加新消息的某种机制。这就是您在ISyncronizeInvoke实现内部需要做的,调用该机制。

System.Timers.Timer可以用于触发事件,如果您愿意在系统池的线程上引发事件。

如果您需要在具有更多控制的控制台应用程序中有一个定时回调,您可以CreateThread您自己的附加线程,有这个WaitForSingleObject,并在前台任务运行时让事件中断前台任务。

有关类似的讨论,请参阅.Net Timeouts:WaitForSingleObject与Timer。

最新更新