在我们无法重现的生产环境中,我们会定期关闭Windows服务.可能需要几个月才能再次发生.
我正在进行一些诊断尝试并帮助解决这个问题,我正在考虑的一件事是在我们开始关闭应用程序后将事件添加到系统线程池60秒.我们的应用程序应在10秒内完全关闭.
在这种情况下,我想跟踪进程的剩余运行线程到事件日志.
我可以使用System.Diagnostics.Process.GetCurrentProcess.Threads获取正在运行的线程.这些线程对象具有本机Win32线程ID等.
我想知道是否有任何方法可以从这些线程ID返回到它们在当前进程中表示的任何托管线程.我试图这样做的原因是因为我们的线程池和其他线程产生了我们给出了代表它们的目的的名称,它真的有助于把它们拿回来.
我正在使用CLR内存诊断库来获取正在运行的进程中所有线程的堆栈跟踪:
        var result = new Dictionary<int, string[]>();
        var pid = Process.GetCurrentProcess().Id;
        using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive))
        {
            string dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation();
            var runtime = dataTarget.CreateRuntime(dacLocation); //throws exception
            foreach (var t in runtime.Threads)
            {
                result.Add(
                    t.ManagedThreadId,
                    t.StackTrace.Select(f =>
                    {
                        if (f.Method != null)
                        {
                            return f.Method.Type.Name + "." + f.Method.Name;
                        }
                        return null;
                    }).ToArray()
                );
            }
        }
我从这里得到这个代码,它似乎适用于其他人,但它在指定的行上抛出了一个异常,带有消息This runtime is not initialized and contains no data.
dacLocation 被设为 C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\mscordacwks.dll
.NET(VB.NET或C#)是否有一种方法,当发生异常时,转储每个线程的堆栈跟踪?基本上我想重现Visual Studio的Debug-> Threads窗口中发生的事情,看看发生异常时每个线程正在做什么