Hallo,
ich habe eine Klasse entwickelt welche eine Interprozesskommunikation über MemoryMappedFiles realisiert.
Problem: Wenn ein Prozess sich nicht richtig beendet und abstürzt, bekommen das die Kommunikationspartner nicht mit, wodurch die Kommunikation stehen bleibt (weil gewartet wird bis jeder die aktuelle Nachricht empfangen hat).
Nun dachte ich mir, ich könnte das Problem einfach lösen, wenn jeder Kommunikationsteilnehmer seine ManagedThreadId registriert. Bleibt die Kommunikation stehen, so mein Plan, wird nachgeschaut ob alle regestierten Threads leben und wenn nicht, gibt es eine Fehlerbehandlung.
Schwierigkeit: Wie kann ich alle ManagedThreadId von einen Process abrufen?
Grüße, Stu
Wenn du alle Threads von deinem eigenen Prozess haben willst sollte:
System.Diagnostics.Process.GetCurrentProcess().Threads
reichen.
Ansonsten musst du alle beteiligten IPC Prozesse finden. (Mit Process.Get.... )
Danke für deine Antwort!
Über die Funktion
System.Diagnostics.Process.GetCurrentProcess().Threads
bekomme ich zwar Id´s, die beziehen sich jedoch auf unmanaged Threads. Meine managed Threads sind da leider nicht enthalten.
An die ProcessId hab ich auch schon gedacht, das gibt aber Probleme wenn ich aus dem gleichen Process, aber mit unterschiedlichen AppDomains, arbeite. Aber vielleicht könnte ich ja beides, also sowohl die ManagedThreadID als auch die ProcessId speichert.
Du kommst an die Managed Threads nur über einen .NET Debugging Dump.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo Stu42,
das eigentliche Problem kannst du auch anders lösen.
Du könntest ein Timeout einbauen -- wenn in dieser Zeit keine Nachricht kommt, so erneut versuchen. Das ist eine einfache Möglichkeit.
Die Kommunikations-Komponeten könnten auch in eigene AppDomains ausgelagert werden und diese AppDomain wird von einem "Host" überwacht. Bemerkt der Host, dass die AppDomain entladen wurde (da gibt es ein Ereignis) so startet er die AppDomain neu.
Bleibt die Kommunikation stehen, so mein Plan, wird nachgeschaut ob alle regestierten Threads
Im Fall der AppDomains könnten diese geprüft werden, indem der Host diese z.B. als Eigenschaft "veröffentlicht". Die " " deshalb, da hier fürs Veröffentlichen mehrere Wege, je nach konkretem Design deiner Komponente, in Frage kommen.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Danke für eure Tipps!
Ich habe es jetzt so gelöst, dass ich mir die process id und die thread id im mmf speichere. Dauert eine Übertragung dann länger, wird überprüft ob alle beteiligten Prozesse (bei verschieden Prozessen), bzw. alle beteiligten Threads (bei einem Prozess und mehrere AppDomains), noch leben.
Die managed Threads hohle ich mir, wie von Abt schon erwähnt, aus einem Debug dump, welcher mit Microsoft.Diagnostics.Runtime (https://github.com/Microsoft/clrmd) wie folgt erstellt wird:
using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 1000, AttachFlag.Passive))
{
ClrRuntime runtime = target.ClrVersions.First().CreateRuntime();
foreach (ClrThread thread in runtime.Threads)
{
//..
}
}
Da ein Kommunikationsabbruch der Fehlerfall ist, hoffe ich das die Lösung mit dem Debug-Dump in der Praxis nicht zu weiteren Fehlern führt.
Falls interesse an der kleinen IPC-Klasse besteht, kann ich diese gerne hier mit kleinem Beispiel mit einfügen.
Hallo Stu42,
Falls interesse an der kleinen IPC-Klasse besteht, kann ich diese gerne hier mit kleinem Beispiel mit einfügen.
Ja bitte. Überleg dich ob es für .NET-Komponenten und C#-Snippets passend ist.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"