Tak więc właśnie musiałem wymyślić, jak to zrobić - nie korzystałem jeszcze z tego rozwiązania w produkcji, ale jest tam stosunkowo nowa biblioteka o nazwie ClrMd.
http://blogs.msdn.com/b/dougste/archive/2013/05/04/clrmd-net-crash-dump-and-live-process-inspection.aspx
Używając go, jestem w stanie dołączyć do własnego procesu i uzyskać ślad stosu dla wszystkich wątków na żywo.Stosując ten po wykryciu zakleszczenia przed ponownym naszą aplikację tak:
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);
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()
);
}
}
var json = JsonConvert.SerializeObject(result);
zip.AddEntry("_threads.json", json);
Naprawdę ważną rzeczą, aby ta do pracy z tego samego procesu jest AttachFlag.Passive
Jeśli po prostu zrobić DataTarget.AttachToProcess(pid, 5000)
, to zrobi "inwazyjny" załącznik, który próbuje wstrzymać proces. Wywołuje to wyjątek podczas próby dołączenia do własnego procesu, zakładam, że nie można wstrzymać aplikacji, próbując dołączyć z aplikacji lub coś podobnego.
W każdym razie, tak, całkiem fajne rzeczy.
Jeśli ktoś ma jakieś powody, dla których jest super naiwny, lub cokolwiek, proszę je wskazać. Nie użyłem go jeszcze w produkcji (po prostu wypuść pierwszą instancję), mając nadzieję, że to zadziała.
co chcesz zrobić z wątkami? – Simon