I have a multithreaded WPF application that is using > 600 threads after is has been running for more than 8 hours. All but approximately 10 of these threads have a stack trace that is very similar to this:
Stack trace 1:
ntkrnlpa.exe!NtInitialUserProcessBuffer+0x7b
ntkrnlpa.exe!MiAddWorkingSetPage+0x174
ntkrnlpa.exe!MiAddWsleHash+0x12a
ntkrnlpa.exe!PopSystemButtonHandler+0x141
ntkrnlpa.exe!KiInterruptTemplate+0x62
ntdll.dll!KiFastSystemCallRet
ntdll.dll!ZwWaitForMultipleObjects+0xc
KERNEL32.dll!WaitForMultipleObjectsEx+0x12c
mscorwks.dll!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f
mscorwks.dll!Thread::DoAppropriateAptStateWait+0x3c
mscorwks.dll!Thread::DoAppropriateWaitWorker+0x13c
mscorwks.dll!Thread::DoAppropriateWait+0x40
mscorwks.dll!WaitHandleNative::CorWaitOneNative+0x156
mscorlib.ni.dll+0x1f68af
mscorlib.ni.dll+0x1caa17
WindowsBase.ni.dll+0x24ac34
WindowsBase.ni.dll+0x2aeb1e
WindowsBase.ni.dll+0x9445d
WindowsBase.ni.dll+0x9267f
mscorwks.dll!JITutil_IsInstanceOfAny+0x106
mscorlib.ni.dll+0x1e842f
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!MethodDesc::CallDescr+0x19c
mscorwks.dll!MethodDesc::CallTargetWorker+0x1f
mscorwks.dll!MethodDescCallSite::Call+0x1a
mscorwks.dll!ExecuteCodeWithGuaranteedCleanupHelper+0x9f
mscorwks.dll!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0x10f
mscorlib.ni.dll+0x235677
mscorlib.ni.dll+0x2202a5
mscorlib.ni.dll+0x1e839b
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!DispatchCallBody+0x1e
mscorwks.dll!DispatchCallDebuggerWrapper+0x3d
mscorwks.dll!DispatchCallNoEH+0x51
mscorwks.dll!AddTimerCallback_Worker+0x66
mscorwks.dll!Thread::DoADCallBack+0x32a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0xe3
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x30a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x33e
mscorwks.dll!ManagedThreadBase::ThreadPool+0x13
mscorwks.dll!AddTimerCallbackEx+0x83
mscorwks.dll!AddTimerCallback+0x10
mscorwks.dll!ThreadpoolMgr::AsyncTimerCallbackCompletion+0x64
mscorwks.dll!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x9a
mscorwks.dll!ThreadpoolMgr::ExecuteWorkRequest+0xaf
mscorwks.dll!ThreadpoolMgr::WorkerThreadStart+0x20b
mscorwks.dll!Thread::intermediateThreadProc+0x49
KERNEL32.dll!BaseThreadStart+0x37
Stack Trace 2:
ntkrnlpa.exe!NtInitialUserProcessBuffer+0x7b
ntkrnlpa.exe!MiAddWorkingSetPage+0x174
ntkrnlpa.exe!MiAddWsleHash+0x12a
ntkrnlpa.exe!PopSystemButtonHandler+0x141
ntkrnlpa.exe!KiInterruptTemplate+0x62
ntdll.dll!KiFastSystemCallRet
ntdll.dll!ZwWaitForMultipleObjects+0xc
KERNEL32.dll!WaitForMultipleObjectsEx+0x12c
mscorwks.dll!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f
mscorwks.dll!Thread::DoAppropriateAptStateWait+0x3c
mscorwks.dll!Thread::DoAppropriateWaitWorker+0x13c
mscorwks.dll!Thread::DoAppropriateWait+0x40
mscorwks.dll!WaitHandleNative::CorWaitOneNative+0x156
mscorlib.ni.dll+0x1f68af
mscorlib.ni.dll+0x1caa17
WindowsBase.ni.dll+0x24ac34
WindowsBase.ni.dll+0x2aeb1e
WindowsBase.ni.dll+0x9445d
WindowsBase.ni.dll+0x9267f
mscorwks.dll!JITutil_IsInstanceOfAny+0x106
mscorlib.ni.dll+0x1e842f
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!MethodDesc::CallDescr+0x19c
mscorwks.dll!MethodDesc::CallTargetWorker+0x1f
mscorwks.dll!MethodDescCallSite::Call+0x1a
mscorwks.dll!ExecuteCodeWithGuaranteedCleanupHelper+0x9f
mscorwks.dll!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0x10f
mscorlib.ni.dll+0x235677
mscorlib.ni.dll+0x2202a5
mscorlib.ni.dll+0x1e839b
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!DispatchCallBody+0x1e
mscorwks.dll!DispatchCallDebuggerWrapper+0x3d
mscorwks.dll!DispatchCallNoEH+0x51
mscorwks.dll!AddTimerCallback_Worker+0x66
mscorwks.dll!Thread::DoADCallBack+0x32a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0xe3
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x30a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x33e
mscorwks.dll!ManagedThreadBase::ThreadPool+0x13
mscorwks.dll!AddTimerCallbackEx+0x83
mscorwks.dll!AddTimerCallback+0x10
mscorwks.dll!ThreadpoolMgr::AsyncTimerCallbackCompletion+0x64
mscorwks.dll!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x9a
mscorwks.dll!ThreadpoolMgr::ExecuteWorkRequest+0xaf
mscorwks.dll!ThreadpoolMgr::WorkerThreadStart+0x20b
mscorwks.dll!Thread::intermediateThreadProc+0x49
KERNEL32.dll!BaseThreadStart+0x37
Application uses System.Threading.Timer to periodically poll for data from several webservices using a WCF client proxy and at any giving time, could be making about 20 of these requests at the same time. Each call to a webservice instantiates a new proxy instance but the client is always closed when a response is received from the webservice.
Application also manipulates with bitmaps for a GIS and this is also done on a periodic interval. No where in code am I explicitly creating threads besides localized usage of the Timer class to poll for data periodically. The GIS does
use the BackgroundWorker but they do limit the thread count.
Anyone have an idea on what is spawning these new threads and why they are not being disposed?
TIA.
Yeah, looks like something you shouldn’t ignore. They are the threadpool thread that the Timer class uses to make the callback. They are deadlocked, looks like they are waiting for a method call that’s marshaled by COM to complete. There should be another thread in your program, one of the other 10 on which you created the GIS object. That thread is not pumping a message loop, a hard requirement for an STA thread that creates single apartment threaded COM components. Or it is stuck itself, not re-entering the message loop. Getting a managed stack trace ought to make it easier to see where the thread is stuck.
Trying to use threads on a COM object that explicitly doesn’t support them (very few do) is pointless. Be sure to create the GIS object on your program’s main UI thread. And use a DispatcherTimer. Creating your own STA thread that pumps a message loop can be a solution when the GIS component is taking too much of a hit on your user interface.