may help you . System.Threading.Timer has my vote. System.Timers.Timer is meant for use in server-based (your code is running as a server/service on a host machine rather than being run by a user) timer functionality.
System.Timers.Timer need to get back to 'Main' thread
Does that help If Foo is not a UI thread and you need to invoke code to execute on it from a different thread you will need to capture the synchronization context which executes Foo and then invoke your code from the timer on it. Take a look at the SynchronizationContext class. You can either Post (asynchronously) or Send a delegate to be executed on a specific, previously captured, synchronization context.
Thread-safety of System.Timers.Timer vs System.Threading.Timer
Hope this helps No, that's not the way it works. The .NET asynchronous Timer classes are perfectly thread-safe. The problem with thread-safety is that it is not a transitive property, it doesn't make the other code that's executed thread-safe as well. The code that you wrote, not a .NET Framework programmer. It is the same kind of problem with the very common assumption that Windows UI code is fundamentally thread-unsafe. It is not, the code inside Windows is perfectly thread-safe. The problem is all the code that runs that is not part of Windows and not written by a Microsoft programmer. There's always a lot of that code, triggered by a SendMessage() call. Which runs custom code that a programmer wrote. Or code he didn't write, like a hook installed by some utility. Code that assumes that the program doesn't make it difficult and just executes message handlers on one thread. He usually does, not doing that buys him a lot of trouble.
c# - System.Timers.Timer Elapsed event on main thread
Hope this helps 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:
var nextMesage = someQueueOfMessages.Dequeue();
System.Timers.Timer.SynchronizingObject ManagedThreadId not from Main Thread