简体   繁体   中英

c# - System.Timers.Timer Elapsed event on main thread

"Simple" question, in a console application, how can we make a System.Timers.Timer Elapsed event be called in the main thread?

I've read something about the SyncronizingObject property but, currently I had no sucess in trying to implement a class which implements ISyncronizeInvoke interface.

EDIT (for clarification):

I'm trying to simulate a classic event model. I have some code which watches for the state of some devices using an event based approach. The problem is that some of the devices don't send their statuses using events and require the application to poll for the data.

The solution found was to use a timer and poll the devices. If any change was detected, then we would raise a similar event of the existing ones.

The problem is that the legacy code is far from thread safe and adapting it would be quite a quest.

Maybe there's a better approach.

Your main thread needs to first have a message loop of some sort, and a mechanism of sending messages to that message loop. If you were in a desktop UI environment such as winforms, WPF, etc., this would be created for you, but since you're not, you need to create one yourself.

A message loop, at it's most primative level, looks something like this:

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

Then of course you need to expose some way for people to add messages to that queue, and potentially some way of indicating that the application should exit at some point. Your queue should also block if there are no items, rather than crashing and burning.

You could do all of this yourself if you wanted. Unless it needs to be particularly fancy, it's not all that time consuming.

Other options would be to use something else to create the message loop, such as Application.Run , which will internally have a loop that looks kinda-sorta like what I showed, under the hood.

Once you have created, or decided upon, your implementation of a message pump, you get with it some mechanism of adding a new message to the pump. That's what you need to do inside of your ISyncronizeInvoke implementation, call out to that mechanism.

System.Timers.Timer can be used to trigger events if you are happy to have the event raised on a thread from the system pool.

If you need to have a timed callback in a console application with more control, you can CreateThread your own additional thread, have this WaitForSingleObject and have the event interrupt the foreground task while it is running.

See .Net Timeouts: WaitForSingleObject vs Timer for a similar discussion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM