Per System.Timers.Timer, su thread separato, se SynchronizingObject non è impostato.
static System.Timers.Timer DummyTimer = null;
static void Main(string[] args)
{
try
{
Console.WriteLine("Main Thread Id: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
DummyTimer = new System.Timers.Timer(1000 * 5); // 5 sec interval
DummyTimer.Enabled = true;
DummyTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnDummyTimerFired);
DummyTimer.AutoReset = true;
DummyTimer.Start();
Console.WriteLine("Hit any key to exit");
Console.ReadLine();
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
return;
}
static void OnDummyTimerFired(object Sender, System.Timers.ElapsedEventArgs e)
{
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
return;
}
Output che vedresti se DummyTimer si attivasse con un intervallo di 5 secondi:
Main Thread Id: 9
12
12
12
12
12
...
Quindi, come visto, OnDummyTimerFired viene eseguito sul thread Workers.
No, ulteriore complicazione: se riduci l'intervallo a dire 10 ms,
Main Thread Id: 9
11
13
12
22
17
...
Questo perché se l'esecuzione precedente di OnDummyTimerFired non viene eseguita quando viene attivato il tick successivo, .NET creerebbe un nuovo thread per eseguire questo lavoro.
A complicare ulteriormente le cose, "La classe System.Timers.Timer fornisce un modo semplice per affrontare questo dilemma: espone una proprietà SynchronizingObject pubblica. L'impostazione di questa proprietà su un'istanza di un Windows Form (o un controllo su un Windows Form) garantirà che il codice nel gestore dell'evento Elapsed venga eseguito sullo stesso thread in cui è stata creata l'istanza di SynchronizingObject. "
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S2