Search code examples
c#winapitask-parallel-librarythreadpoolntdll

Is this stack trace ending with _NtWaitForSingleObject@12() indicating a blocked or an idle thread?


I have an application that makes heavy use of the Task Parallel Library. As my application runs, I notice that the number of threads reported being used by ProcessExplorer at times exceeds 200 threads for my application and eventually the application will lock when it runs out of threads.

When a I took a FULL DUMP of the memory using AdPlus and opened it in Visual Studio, I saw 82 threads running at that time (although ProcessExplorer reported over 100 at the time).

Many of those threads (42 of them) show only the following stack trace:

ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

My question is:

Are the threads with the above stack trace waiting for something that I kicked off and subsequently orphaned? Or does that stack trace just indicate an idle thread?


Solution

  • So it turns out that WinDbg really was the best way to get a definitive answer to the question of what all those threads are doing.

    As theB statated, '_NtWaitForSingleObject@12 indicates that the thread is either idle waiting for work or waiting for the scheduler'

    Using the !threadpool command in WinDbg, the following clearly indicates that these threads must be owned by the threadpool and that they are indeed idle:

    0:073> !threadpool
    CPU utilization: 21%
    Worker Thread: Total: 256 Running: 2 Idle: 254 MaxLimit: 1023 MinLimit: 256
    Work Request in Queue: 0
    --------------------------------------
    Number of Timers: 1
    --------------------------------------
    Completion Port Thread:Total: 1 Free: 1 MaxFree: 4 CurrentLimit: 1 MaxLimit: 1000 MinLimit: 256