看到很多clr!CLRSemaphore ::等待调用堆栈

时间:2016-08-12 01:55:14

标签: c# multithreading debugging threadpool windbg

我们看到很多像下面这样的callstack,我可以知道会发生什么情况\情况会发生吗?

Error

1 个答案:

答案 0 :(得分:5)

正如评论中@Harry Johnston所提到的那样,这些是线程池的工作线程无关。

以下示例可用于复制此类堆栈。它将创建12个线程池工作线程,当调试器中断时,它们都处于空闲状态,如您所见。

该代码基于Microsoft的Fibunacci threadpool example

using System.Diagnostics;
using System.Threading;

public class Fibonacci
{
    public void ThreadPoolCallback(object threadContext)
    {
        FibOfN = Calculate(N);
        DoneEvent.Set();
    }

    public int Calculate(int n)
    {
        if (n <= 1) return n;
        return Calculate(n - 1) + Calculate(n - 2);
    }

    public int N { get; set; }
    public int FibOfN { get; private set; }
    public ManualResetEvent DoneEvent { get; set; }
}

public class ClrSemaphoreWaitDemo
{
    static void Main()
    {
        const int numberOfTasks = 12;
        var doneEvents = new ManualResetEvent[numberOfTasks];
        var fibArray = new Fibonacci[numberOfTasks];
        ThreadPool.SetMaxThreads(numberOfTasks, numberOfTasks);
        ThreadPool.SetMinThreads(numberOfTasks, numberOfTasks);

        for (int i = 0; i < numberOfTasks; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            fibArray[i] = new Fibonacci {N= 4, DoneEvent= doneEvents[i]};
            ThreadPool.QueueUserWorkItem(fibArray[i].ThreadPoolCallback, i);
        }

        WaitHandle.WaitAll(doneEvents);
        Debug.WriteLine("Now run .symfix; .reload; .loadby sos clr; !threads; !threads; !findstack clr!CLRSemaphore::Wait");
        Debugger.Break();
    }
}

当调试器中断时,运行以下命令:

.symfix; .reload; .loadby sos clr; !threads; !threads; !findstack clr!CLRSemaphore::Wait