Hi,
I like to know how many threads are used by a Threading.Timer object.
When I create a Threading.Timer object calling a short running method
every 5 seconds I expected to have one additional ThreadPool thread.
And that is exactly what MS VIsual Studio shows.
But when I run Processexplorer or Taskmanager I see 2 additional
threads, after a while another 2 additional threads. With the 3 threads
at start time we have totally 7 threads.
Please follow the code below to get the locations of the threads.
Does anyone know
1. Where do the three start threads come from (UI thread, GC?, and ?)
2. Does the timer itself consumes permanently a thread? Not only the
method he invokes? This would explain why we get two additional
threads.
If yes, is it a ThreadPool thread?
3. Why do we see another pair of additional threads?
4. Is it dangerous to use many Threading.Timer objects (even for
shortrunning methods)=
// program to demonstrate thread usage by Threading.Timer
using System;
using System.Threading;
namespace NS_ThreadingTimer
{
class TimerState
{
public int counter = 0; // thread parameter
public volatile Timer tmr; // timer reference needed for disposing
}
class App
{
public static void Main()
{
Console.WriteLine("starting timer, press ENTER ...");
Console.ReadLine();
// VisualStudio shows here one thread:
// NS_ThreadingTimer.App.Main (location)
// ProcessExplorer and TaskManager shows here 3 threads:
// mscoree.dll!_CorExeMain
// mscorwks.dll!DebuggerRCThread::ThreadProcStatic
// mscorwks.dll!Thread::intermediateThreadProc
// start timer immediately, then invoke CheckStatus every 5
seconds.
TimerState s = new TimerState();
TimerCallback timerDelegate = new TimerCallback (CheckStatus);
Timer timer = new Timer (timerDelegate, s, 0, 5000);
s.tmr = timer; // Keep handle to timer, so it can be disposed.
while (s.tmr != null) // Main thread NOP until timer is disposed.
Thread.Sleep(1000);
// VisualStudio shows 2 threads:
// NS_ThreadingTimer.App.Main (location)
// System.IO.__ConsoleStream.ReadFileNative
// ProcessExplorer and TaskManager shows here 7 threads:
// mscoree.dll!_CorExeMain
// mscorwks.dll!DebuggerRCThread::ThreadProcStatic
// mscorwks.dll!Thread::intermediateThreadProc
// mscorwks.dll!ThreadpoolMgr::TimerThreadStart
// mscorwks.dll!ThreadpoolMgr::intermediateThreadProc
// mscorwks.dll!ThreadpoolMgr::intermediateThreadProc
// mscorwks.dll!ThreadpoolMgr::GateThreadStart
Console.WriteLine("Timer example done, press ENTER to continue
....");
Console.ReadLine();
}
static void CheckStatus(Object state)
{
// VisualStudio shows 2 threads:
// NS_ThreadingTimer.App.Main (location)
// NS_ThreadingTimer.App.CheckStatus (location)
// ProcessExplorer and TaskManager shows here 7 threads:
// mscoree.dll!_CorExeMain
// mscorwks.dll!DebuggerRCThread::ThreadProcStatic
// mscorwks.dll!Thread::intermediateThreadProc
// mscorwks.dll!ThreadpoolMgr::TimerThreadStart
// mscorwks.dll!ThreadpoolMgr::intermediateThreadProc
// mscorwks.dll!ThreadpoolMgr::intermediateThreadProc
// mscorwks.dll!ThreadpoolMgr::GateThreadStart
TimerState s =(TimerState) state;
s.counter++;
Console.WriteLine("{0}: {1}.", DateTime.Now.TimeOfDay,
s.counter);
if (s.counter == 10)
{
s.tmr.Dispose();
s.tmr = null;
}
}
}
}
So many questions, but I could not find the answer out of the docs.
Greetings,
Michael Heitland