C# 如何在.NET中进行线程转储?(一个JVM线程转储)
我没有找到在.NET中的所有线程上转储堆栈的方法。既不是要发送给进程的信号,也不是对所有线程的编程访问。我只能通过thread.CurrentThread访问当前线程C# 如何在.NET中进行线程转储?(一个JVM线程转储),c#,.net,C#,.net,我没有找到在.NET中的所有线程上转储堆栈的方法。既不是要发送给进程的信号,也不是对所有线程的编程访问。我只能通过thread.CurrentThread访问当前线程 有什么窍门吗?系统中有各种方便的类。诊断可以帮助您调试和收集各种跟踪信息,例如StackTrace 有一个不可靠的进程类,可以用来获取执行线程的数量,但很少有细节。使用以下代码段: Using System.Diagnostics; var threads = Process.GetCurrentProcess().Threa
有什么窍门吗?系统中有各种方便的类。诊断可以帮助您调试和收集各种跟踪信息,例如StackTrace 有一个不可靠的进程类,可以用来获取执行线程的数量,但很少有细节。使用以下代码段:
Using System.Diagnostics;
var threads = Process.GetCurrentProcess().Threads;
好的,在看了多一点之后,看起来捕获所有当前堆栈的最简单方法是通过一个迷你转储和一个工具,比如或者如果您正在运行vista
祝你好运。我为过去参与的一个项目编写了一个转储程序:
void CrashHandler::WriteThreadInfo(StringWriter* sw, ArrayList* threads, String* type)
{
sw->WriteLine(type);
IEnumerator* ie = threads->GetEnumerator();
while(ie->MoveNext())
{
botNETThread* bnt = static_cast<botNETThread*>(ie->Current);
if(!bnt->IsAlive) continue;
sw->WriteLine(String::Concat(S"ORIGIN ASSEMBLY: ", bnt->Assembly->FullName));
sw->WriteLine(String::Concat(S"THREAD NAME: ", (bnt->Name && bnt->Name->Length)?bnt->Name:S"Unnamed thread"));
sw->Write(GetStackTrace(bnt->_thread));
sw->WriteLine();
sw->WriteLine();
}
}
String* CrashHandler::GetStackTrace(Thread* t)
{
System::Diagnostics::StackTrace __gc * trace1 = __gc new System::Diagnostics::StackTrace(t, true);
System::String __gc * text1 = System::Environment::NewLine;
System::Text::StringBuilder __gc * builder1 = __gc new System::Text::StringBuilder(255);
for (System::Int32 num1 = 0; (num1 < trace1->FrameCount); num1++)
{
System::Diagnostics::StackFrame __gc * frame1 = trace1->GetFrame(num1);
builder1->Append(S" at ");
System::Reflection::MethodBase __gc * base1 = frame1->GetMethod();
System::Type __gc * type1 = base1->DeclaringType;
if (type1 != 0)
{
System::String __gc * text2 = type1->Namespace;
if (text2 != 0)
{
builder1->Append(text2);
if (builder1 != 0)
{
builder1->Append(S".");
}
}
builder1->Append(type1->Name);
builder1->Append(S".");
}
builder1->Append(base1->Name);
builder1->Append(S"(");
System::Reflection::ParameterInfo __gc * infoArray1 __gc [] = base1->GetParameters();
for (System::Int32 num2 = 0; (num2 < infoArray1->Length); num2++)
{
System::String __gc * text3 = S"<UnknownType>";
if (infoArray1[num2]->ParameterType != 0)
{
text3 = infoArray1[num2]->ParameterType->Name;
}
builder1->Append(System::String::Concat(((num2 != 0) ? S", " : S""), text3, S" ", infoArray1[num2]->Name));
}
builder1->Append(S")");
if (frame1->GetILOffset() != -1)
{
System::String __gc * text4 = 0;
try
{
text4 = frame1->GetFileName();
}
catch (System::Security::SecurityException*)
{
}
if (text4 != 0)
{
builder1->Append(System::String::Concat(S" in ", text4, S":line ", frame1->GetFileLineNumber().ToString()));
}
}
if (num1 != (trace1->FrameCount - 1))
{
builder1->Append(text1);
}
}
return builder1->ToString();
}
void CrashHandler::WriteThreadInfo(StringWriter*sw、ArrayList*线程、String*类型)
{
sw->WriteLine(类型);
IEnumerator*ie=threads->GetEnumerator();
而(ie->MoveNext())
{
botNETThread*bnt=static_cast(ie->Current);
如果(!bnt->IsAlive)继续;
sw->WriteLine(字符串::Concat(S“ORIGIN ASSEMBLY:”,bnt->ASSEMBLY->FullName));
sw->WriteLine(字符串::Concat(S“THREAD NAME:”,(bnt->NAME&&bnt->NAME->Length)?bnt->NAME:S“Unnamed THREAD”);
sw->Write(GetStackTrace(bnt->u线程));
sw->WriteLine();
sw->WriteLine();
}
}
String*CrashHandler::GetStackTrace(线程*t)
{
System::Diagnostics::StackTrace _gc*trace1=_gc新系统::Diagnostics::StackTrace(t,true);
系统::字符串uu gc*text1=系统::环境::换行符;
System::Text::StringBuilder _gc*builder1=_gc新系统::Text::StringBuilder(255);
对于(System::Int32 num1=0;(num1FrameCount);num1++)
{
系统::诊断::StackFrame\uu gc*frame1=trace1->GetFrame(num1);
builder1->Append(S“at”);
System::Reflection::MethodBase uu gc*base1=frame1->GetMethod();
系统::Type uu gc*type1=base1->DeclaringType;
如果(类型1!=0)
{
系统::字符串uu gc*text2=type1->Namespace;
如果(text2!=0)
{
builder1->Append(text2);
if(builder1!=0)
{
builder1->Append(S)”;
}
}
builder1->Append(类型1->Name);
builder1->Append(S)”;
}
builder1->Append(base1->Name);
builder1->附加“(”);
System::Reflection::ParameterInfo _gc*infoArray1 _gc[]=base1->GetParameters();
对于(System::Int32 num2=0;(num2Length);num2++)
{
系统::字符串uu gc*text3=S“”;
if(infoArray1[num2]->ParameterType!=0)
{
text3=infoArray1[num2]->参数类型->名称;
}
builder1->Append(System::String::Concat(((num2!=0)?S“,”:S“)、text3、S“、infoArray1[num2]->Name));
}
builder1->Append(S“)”;
如果(frame1->GetILOffset()!=-1)
{
系统::字符串uu gc*text4=0;
尝试
{
text4=frame1->GetFileName();
}
捕获(系统::安全::安全例外*)
{
}
如果(text4!=0)
{
builder1->Append(System::String::Concat(S“in”,text4,S“:line”,frame1->GetFileLineNumber().ToString());
}
}
如果(num1!=(trace1->FrameCount-1))
{
builder1->Append(text1);
}
}
返回builder1->ToString();
}
您可以使用Process.GetCurrentProcess().Threads来获取线程
我知道我是用C++来管理的,但是很容易遵循。我使用了一个线程数组列表,因为为了我的目的,我对线程进行了分类。是的,我使用了以前编写的堆栈帧代码,因为我当时是MC++新手:)
整个文件是。这是我不久前写的一篇文章。为了省去其他人的麻烦,这里是上面到c的端口:
static void WriteThreadInfo(StringBuilder软件,IEnumerable线程)
{
foreach(线程中的线程)
{
如果(!thread.IsAlive)继续;
Append(String.Concat(“线程名称:”,THREAD.NAME));
sw.Append(GetStackTrace(线程));
sw.AppendLine();
sw.AppendLine();
}
}
静态字符串GetStackTrace(线程t)
{
t、 暂停();
var trace1=新堆栈跟踪(t,真);
t、 恢复();
字符串text1=System.Environment.NewLine;
var builder1=新的StringBuilder(255);
for(Int32 num1=0;(num1 static void WriteThreadInfo(StringBuilder sw, IEnumerable<Thread> threads)
{
foreach(Thread thread in threads)
{
if(!thread.IsAlive) continue;
sw.Append(String.Concat("THREAD NAME: ", thread.Name));
sw.Append(GetStackTrace(thread));
sw.AppendLine();
sw.AppendLine();
}
}
static String GetStackTrace(Thread t)
{
t.Suspend();
var trace1 = new StackTrace(t, true);
t.Resume();
String text1 = System.Environment.NewLine;
var builder1 = new StringBuilder(255);
for (Int32 num1 = 0; (num1 < trace1.FrameCount); num1++)
{
StackFrame frame1 = trace1.GetFrame(num1);
builder1.Append(" at ");
System.Reflection.MethodBase base1 = frame1.GetMethod();
Type type1 = base1.DeclaringType;
if (type1 != null)
{
String text2 = type1.Namespace;
if (text2 != null)
{
builder1.Append(text2);
builder1.Append(".");
}
builder1.Append(type1.Name);
builder1.Append(".");
}
builder1.Append(base1.Name);
builder1.Append("(");
System.Reflection.ParameterInfo [] infoArray1 = base1.GetParameters();
for (Int32 num2 = 0; (num2 < infoArray1.Length); num2++)
{
String text3 = "<UnknownType>";
if (infoArray1[num2].ParameterType != null)
{
text3 = infoArray1[num2].ParameterType.Name;
}
builder1.Append(String.Concat(((num2 != 0) ? ", " : ""), text3, " ", infoArray1[num2].Name));
}
builder1.Append(")");
if (frame1.GetILOffset() != -1)
{
String text4 = null;
try
{
text4 = frame1.GetFileName();
}
catch (System.Security.SecurityException)
{
}
if (text4 != null)
{
builder1.Append(String.Concat(" in ", text4, ":line ", frame1.GetFileLineNumber().ToString()));
}
}
if (num1 != (trace1.FrameCount - 1))
{
builder1.Append(text1);
}
}
return builder1.ToString();
}
mse /s /p <pid>
using Microsoft.Diagnostics.Runtime;
using (DataTarget target = DataTarget.AttachToProcess(
Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive))
{
ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
foreach (ClrThread thread in runtime.Threads)
{
IList<ClrStackFrame> stackFrames = thread.StackTrace;
PrintStackTrace(stackFrames);
}
}