Gelöst JTLwawiExtern.dll Crash beim Beenden der Applikation

t.oster

Gut bekanntes Mitglied
4. Dezember 2013
191
19
Hallo,
ich habe auf Basis dieser Doku http://developer.jtl-software.de/projects/jtl-wawi-externe-entwickler/wiki ein kleines Tool entwickelt, welches Workflows in der Wawi mit Hilfe der JTLwawiExtern.dll ausführt. Funktioniert auch alles ganz gut, nur dass die Ausführungszeit der Workflows immer langsamer wird, bis das Tool neu gestartet wird (Ressourcen/Memoryleak?). Um das zu Umgehen wird das Tool einfach mehrmals am Tag neu gestartet. In neun von zehn Fällen funktioniert das wunderbar, aber manchmal gibt es beim beenden einen AppCrash. Ich habe versucht das ganze in einem Debugger zu öffnen, aber anscheinend kommt der Crash erst nachdem mein Programm beendet wurde, wenn versucht wird die offenen Threads zu beenden.

Die genaue Fehlermeldung ist
Code:
Ausnahmefehler bei 0x7772df51 (ntdll.dll) in WorkflowRunner.exe: 0xC0000025

Hier ein paar Screenshots vom StackTrace:
Bildschirmfoto vom 2016-08-12 15:39:53.png Bildschirmfoto vom 2016-08-12 15:40:31.png Bildschirmfoto vom 2016-08-12 15:40:41.png Bildschirmfoto vom 2016-08-12 15:40:51.png Bildschirmfoto vom 2016-08-12 15:41:04.png Bildschirmfoto vom 2016-08-12 15:41:13.png

Ich bin kein C# Entwickler und kann nicht ausschliessen, dass der Fehler auf meiner Seite liegt, aber ist es vielleicht möglich, dass die Ursache in der JTLwawiExtern.dll liegt? Ist vielleicht unter Umständen noch ein Thread oder eine Datenbankverbindung offen, die nicht sauber beendet wird, wenn man das Programm (Consoleapp) über Environment.Exit bzw return der Main Funktion beendet? Hat jemand anders auch schon Probleme mit App Crashes gehabt? Vielleicht kann man eine "unload" Funktion noch einbauen, die alles sauber beendet?
 

Marc Völker

Moderator
Mitarbeiter
15. April 2014
1.886
191
Hürth
Hi,

haben das Problem indirekt auch. Glaub Marc von Unicorn umgeht das, weil er das programm für jeden aufruf neu aufruft. Wir lösen das über einen eigenen Service und AppDomain Abstraktion, wo ich diese regelmäßig Recycle

P.S. Mein Service wird dann per Rest angesprochen und gibt das an die JtlWawiExtern.dll weiter.
 

t.oster

Gut bekanntes Mitglied
4. Dezember 2013
191
19
Hi, kommt es dann bei der eigenen AppDomain Abstratkion nicht mehr zu Crashes? Ich habe inzwischen auch einen Webservice der das Programm automatisch neu startet, aber die alte Instanz hängt bei mir, bis ich den AppCrash weg clicke. Das kann man zwar per AutoIt automatisieren, aber sowas möchte man natürlich nicht beim Kunden haben.
Das Programm für jeden Aufruf neu starten ist schlecht, weil bei mir dauert z.B. der erste Workflow 5s, während weitere dann im Bereich 0,5 bis 1s sind. Der Crash kommt bei mir immer nur beim Beenden der Applikation, also scheint da irgendein Finalizer in der DLL zu hängen (?).

Wenn Sie mir einen Tipp geben könnten, wie ich den Crash zumindest programmatisch abfangen kann, wäre das schonmal eine große Hilfe.
 

Marc Völker

Moderator
Mitarbeiter
15. April 2014
1.886
191
Hürth
Hi,

joar immer neustarten kamm für mich auch nicht in frage. Die Exception kann ja ruhig kommen, nur wird halt intern gehandelt. Und beim Unload der AppDomain wird halt alles entladen. Daher keine Probleme
 

t.oster

Gut bekanntes Mitglied
4. Dezember 2013
191
19
Hi, hab jetzt mal versucht den Code in ner anderen AppDomain zu starten usw, aber trotzdem lässt sich die Exception nicht fangen. Könnten Sie evtl ein minimales Codegerüst zur Verfügung stellen oder einen Hinweis geben, wie ich es bewerkstelligen kann, dass dieser blöde "Anwendung funktioniert nicht mehr" Dialog nicht aufpoppt?
 

t.oster

Gut bekanntes Mitglied
4. Dezember 2013
191
19
Ich bin leider kein C# Entwickler, aber das hier ist meine Main-Methode samt Klasse:
Code:
using System;
using System.Text;
using System.Diagnostics;

namespace WorkflowRunner
{
    class Program
    {

        public static void exception_handler(object sender, UnhandledExceptionEventArgs e) {
            try
            {
                Exception ex = (Exception)e.ExceptionObject;
                Console.WriteLine("Unhandeled Exception" + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace);
            }
            catch
            {
                Console.WriteLine ("Exception beim LOG schreiben. Wird beendet...");
            }
            finally {
                Process.GetCurrentProcess().Kill();
            }
        }

        [STAThread]
        static void Main(string[] args) {
            AppDomain.CurrentDomain.UnhandledException +=
                new UnhandledExceptionEventHandler (exception_handler);

            try {
                AppDomain newAppDomain = AppDomain.CreateDomain("NewApplicationDomain");
                newAppDomain.UnhandledException += new UnhandledExceptionEventHandler (exception_handler);
                /*
                 * - Wawi Installationspfad finden -> Registry
                 * - JTLwawiExtern finden und Version prüfen
                 * - ALLE JTL Assemblys aus dem Installationspfad laden
                 */
                ValidateAssembly validateAssembly = (ValidateAssembly)newAppDomain.CreateInstanceAndUnwrap("WorkflowRunner", "WorkflowRunner.ValidateAssembly");
                if (!validateAssembly.IsValid) {
                    Console.WriteLine ("Fehler bei Wawi DLL Suche...");
                    return;
                }
                WorkflowRunner proxy = (WorkflowRunner)newAppDomain.CreateInstanceAndUnwrap("WorkflowRunner", "WorkflowRunner.WorkflowRunner");
                proxy.RunProgram (args);
            }
            catch (Exception e) {
                Console.WriteLine ("Got It:..."+e);
                return;
            }
        }
    }
}

Sowohl der vialidateAssembly-Aufruf, welcher die JTL DLLs dynamisch läd, wie im Beispielprojekt beschrieben, als auch meine "RunProgram" Methode werden soweit ich das sehe in der neuen AppDomain aufgerufen.
 

Marc Völker

Moderator
Mitarbeiter
15. April 2014
1.886
191
Hürth
Versuch mal bitte am ende per AppDomain.CurrentDomain.GetAssemblies() alle geladenen auszulesen. Und guck mal was er da so geladen hat.

könnte aber halt auch sein, dass ich die nur deshalb nicht mit bekomme die fehler, weil mein Programm halt als Service gealden ist... Hab das aber aktuell nicht in Kopf, und werde da auch kein Code posten.