Hallo Leute, ich steh mal wieder - ziemlich - auf dem Schlauch. Diesmal aber mit einem generellen Verständnisproblem was die Delegaten und den Asynchronen Aufruf angeht.
Kurzum: ich habe ein WPF-Programm, das einiges an Dingen abarbeitet und darin befindet sich auch eine Instanz von einer Console, die alles, was geloggt werden muss, loggt. Das funktioniert ohne Probleme. Nun möchte ich jedoch eine Applikation (später auch Webseite, etc. ) aus dem Programm heraus starten. Manche Startvorgänge brauchen jedoch einiges an Zeit, bis sie fertig sind, deshalb möchte ich das Starten gerne in einen anderen Thread auslagern. Folgender Code liegt derzeit vor (alles leider in c#, ich hoffe, ihr vergebt mir):
Wir fokussieren uns erstmal nur auf den ersten Teil der Switch-Anweisung: Case: Enums.ApplicationType.Application. Hier soll dann die Funktion ApplicationThread aufgerufen werden. Sie ist wie folgt definiert:
Da nun aber die console sich im Thread der UI befindet, verursachen selbstverständlich die Aufrufe innerhalb der ApplicationThread-Methode Fehler, da sie auf ein Element eines anderen Threads zugreifen möchten.
Ich weiß auch, dass ich mit Delegaten und Invoke() arbeiten müsste, auch, dass WPF eine Dispatcher-Funktion zur Verfügung stellt, um das zu ermöglichen. Doch hier setzt mein Verständnis aus und die beispiele auf Webseiten zeigen immer Code-Schnipsel, die aber nie das Problem beschreiben, auf das ich treffe. Und somit fehlt mir etwas das Verständnis hierfür.
Deshalb zu Frage:
Wie müsste ich generell in der ApplicationThread-Methode auf die console zugreifen, welche als Instanz im MainWindow befindet?
Wo müsste welcher Delegate, welcher Aufruf mit welchen Parametern geschehen, damit ich der Console aus dem Main-Thread sagen kann, sie solle die Logs hinzufügen?
Zur Erläuterung der vielleicht merkwürdig aussehenden ApplicationThread-Methode:
Der innere Try-Catch-Block soll die Process-started-time ermitteln (die liegt aber vielleicht noch nicht vor), deshalb try-catch. Und das soll solange passieren bis es erfolgreich passiert ist. Und diese Zeit möchte ich dann am liebsten in die Console schreiben und danach kann der Prozess verworfen werden. Ebenso wenn es dort zu Fehlern kommt, sollen diese ebenfalls protokolliert werden.
Vielleicht kann mir jemand das Verständnis für diese ganzen Delegaten-Sache an meinem konkreten Beispiel erläutern. Ich brauche auch nicht zwangsläufig "den Code dafür", sondern das generelle Verständnis hierfür (auch wenn es mit Code natürlich eifnacher zu verstehen ist )
Vielleicht kann mir jemand helfen. Wenn noch mehr Code gebraucht wird (ist nur ein seeeeeehr kleiner Auszug meines vollen Programms), dann eifnach sagen, was ihr braucht.
Ich danke euch
Kurzum: ich habe ein WPF-Programm, das einiges an Dingen abarbeitet und darin befindet sich auch eine Instanz von einer Console, die alles, was geloggt werden muss, loggt. Das funktioniert ohne Probleme. Nun möchte ich jedoch eine Applikation (später auch Webseite, etc. ) aus dem Programm heraus starten. Manche Startvorgänge brauchen jedoch einiges an Zeit, bis sie fertig sind, deshalb möchte ich das Starten gerne in einen anderen Thread auslagern. Folgender Code liegt derzeit vor (alles leider in c#, ich hoffe, ihr vergebt mir):
C#-Quellcode
- public static bool ExecuteManagedApp(ManagedApp MA, Console console)
- {
- ArgArray = MA.Args.Split();
- try
- {
- switch (MA.MyType)
- {
- case Enums.AppliactionTypes.Application:
- Thread thread = new Thread(ApplicationThread);
- thread.Start(new object[] {console, MA.Path, MA.Args });
- return true;
- case Enums.AppliactionTypes.Folder:
- Thread thread1 = new Thread(FolderThread);
- thread1.Start(new object[] { MA.Path });
- return true;
- case Enums.AppliactionTypes.Website:
- Thread thread2 = new Thread(WebsiteThread);
- thread2.Start(new object[] { MA.Path });
- return true;
- }
- }
- catch (System.IO.FileNotFoundException)
- {
- console.AddLog("Das angegebene Programm/die Webseite <" + MA.Description + "|" + MA.Path + "> konnte nicht gefunden werden", LogLevel.Error);
- return false;
- }
- catch (System.Exception)
- {
- console.AddLog("Schwerwiegender Fehler durch den Aufruf von <Executer<" + MA.Description + "<" + MA.MyType + "<" + MA.Path + "<" + MA.Args + ">>>>>", LogLevel.Error);
- return false;
- }
Wir fokussieren uns erstmal nur auf den ersten Teil der Switch-Anweisung: Case: Enums.ApplicationType.Application. Hier soll dann die Funktion ApplicationThread aufgerufen werden. Sie ist wie folgt definiert:
C#-Quellcode
- private static void ApplicationThread(object param)
- {
- try
- {
- var t = new string[] { ((param as object[])[1] as string), ((param as object[])[2] as string) };
- System.Diagnostics.Process process = System.Diagnostics.Process.Start(t[0], t[1]);
- while (true)
- {
- try
- {
- var time = process.StartTime;
- ((param as object[])[0] as Console).AddLog("Thread|Start: " + t[0] + " | " + time.ToString(), LogLevel.Detail);
- break;
- }
- catch { }
- }
- }
- catch (System.IO.FileNotFoundException)
- {
- ((param as object[])[0] as Console).AddLog("Das angegebene Programm <" + ((param as object[])[1] as string) + "> konnte nicht gefunden werden", LogLevel.Error);
- }
- catch (System.Exception)
- {
- ((param as object[])[0] as Console).AddLog("Schwerwiegender Fehler durch den Aufruf von <" + ((param as object[])[1] as string) + ">|Application", LogLevel.Error);
- }
- }
Da nun aber die console sich im Thread der UI befindet, verursachen selbstverständlich die Aufrufe innerhalb der ApplicationThread-Methode Fehler, da sie auf ein Element eines anderen Threads zugreifen möchten.
Ich weiß auch, dass ich mit Delegaten und Invoke() arbeiten müsste, auch, dass WPF eine Dispatcher-Funktion zur Verfügung stellt, um das zu ermöglichen. Doch hier setzt mein Verständnis aus und die beispiele auf Webseiten zeigen immer Code-Schnipsel, die aber nie das Problem beschreiben, auf das ich treffe. Und somit fehlt mir etwas das Verständnis hierfür.
Deshalb zu Frage:
Wie müsste ich generell in der ApplicationThread-Methode auf die console zugreifen, welche als Instanz im MainWindow befindet?
Wo müsste welcher Delegate, welcher Aufruf mit welchen Parametern geschehen, damit ich der Console aus dem Main-Thread sagen kann, sie solle die Logs hinzufügen?
Zur Erläuterung der vielleicht merkwürdig aussehenden ApplicationThread-Methode:
Der innere Try-Catch-Block soll die Process-started-time ermitteln (die liegt aber vielleicht noch nicht vor), deshalb try-catch. Und das soll solange passieren bis es erfolgreich passiert ist. Und diese Zeit möchte ich dann am liebsten in die Console schreiben und danach kann der Prozess verworfen werden. Ebenso wenn es dort zu Fehlern kommt, sollen diese ebenfalls protokolliert werden.
Vielleicht kann mir jemand das Verständnis für diese ganzen Delegaten-Sache an meinem konkreten Beispiel erläutern. Ich brauche auch nicht zwangsläufig "den Code dafür", sondern das generelle Verständnis hierfür (auch wenn es mit Code natürlich eifnacher zu verstehen ist )
Vielleicht kann mir jemand helfen. Wenn noch mehr Code gebraucht wird (ist nur ein seeeeeehr kleiner Auszug meines vollen Programms), dann eifnach sagen, was ihr braucht.
Ich danke euch