Laden...

Logging aus einer Berechnung

Erstellt von torti vor 11 Jahren Letzter Beitrag vor 11 Jahren 1.325 Views
T
torti Themenstarter:in
193 Beiträge seit 2006
vor 11 Jahren
Logging aus einer Berechnung

hallo,

ich bin gerade auf der suche nach einer brauchbaren strategie für eine logging lösung. ich habe einen berechnungskern der mehrere minuten rechnet. um den user auf den laufenden zu halten, also dem user zu zeigen was gerade berechnet wird, würde ich gerne in einem eigenen fenster die berechnungsschritte ausgeben welche aktuell im berechnungskern ausgeführt werden. jetzt weiß ich nicht so recht wie ich das angehen soll. meiner meinung nach gibt es mehrere varianten:
*threads *events *backgroundworker

gibt es ev. schon etwas ähnliches, bzw. mit was sollte ich es realisieren?

bin für jeden hinweis dankbar!

danke,
torti

16.806 Beiträge seit 2008
vor 11 Jahren

Ich mach sowas ähnliches und werfe Events über aktuelle Schritte.
Die GUI abonniert dieses und wird so aktualisiert. Eine Berechnung sollte autark arbeiten; dem sollte es also egal sein, ob und welche GUI hier die Mutter der Geschichte ist; daher sehe ich auch alles andere als Events für nicht brauchbar an.

P
67 Beiträge seit 2008
vor 11 Jahren

im grunde hast du alles aufgezählt was nötig ist (achtung: backgroundworker == thread). verkapsel deine berechnung in einen eigenen thread und lasse von dort aus, wie abt bereits erklärte, events hageln. auch hier musst du vorsichtig sein, denn die gui schmeisst gerne fehler, wenn diese aus dem falschen thread aus angesprochen wird, näheres dazu hier (Invoke)

Religionskriege sind Konflikte zwischen erwachsenen Menschen, bei denen es darum geht, wer den cooleren, imaginaeren Freund hat

F
10.010 Beiträge seit 2004
vor 11 Jahren

@torti:
Wo ist da jetzt wirklich das Problem?
Du hast doch ganz bestimmt den von deinem Berwechnungskern benutzen Logger in einem Interface abstrahiert ( oder andersrum dein BK benutzt einen Abstrakten Logger ) und per IOC angebunden.
Also kann dein Berechnungskern seine Schritte hierein loggen.
Er sollte auch weder wissen das das als Live Anzeige gedacht ist noch sollte er wissen das er in einem extra Thread läuft.
Das ist nicht seine Aufgabe.

Ich habe für so etwas einen Spezialisierten Logger, der in eine ObservableCollection loggt ( mit einem Maximum an Zeilen ).

Und dann habe ich ein ListView im virtuellen Modus, das ( im Gui Thread ) diesen Logger bindet.

Alles nett getrennt, jedes für sich sehr einfach, leicht austauschbar und damit leicht wartbar.
Soll nichts mehr angezeigt werden, bekommt der BK eben einen NullLogger.

156 Beiträge seit 2010
vor 11 Jahren

[...] näheres dazu
>

besser ist Control.BeginInvoke-Methode (Delegate) - Invoke synchonisiert mit dem GUI Thread. Das bremst unter Umständen den BK aus.

hand, mogel

D
216 Beiträge seit 2009
vor 11 Jahren
49.485 Beiträge seit 2005
vor 11 Jahren

Hallo zusammen,

Und am besten ist:
>
😃

danke, so sehe ich das auch. 😃

Und dort steht zu lesen:

In vielen Fällen kann man wählen, ob man Control.BeginInvoke oder Control.Invoke benutzt. Der Hauptunterschied ist, dass Invoke wartet, bis der GUI-Thread die Aktion ausgeführt hat, wogegen BeginInvoke den Arbeitsauftrag nur in die Nachrichtenschlange des GUI-Threads stellt und sofort zurückkehrt. Invoke arbeitet also (in vielen Fällen unnötig) synchron. Allerdings muss man bei Control.BeginInvoke jegliche erforderliche Synchronisation beim gleichzeitigen Zugriff auf dieselben Daten selbst realisieren.[...]

Control.BeginInvoke ist deutlich weniger teuer als Control.Invoke. Trotzdem sollte man mit Aufrufen von Control.BeginInvoke genauso sparsam sein, denn jeder Aufruf von Control.BeginInvoke stellt eine Nachricht in die Nachrichtenschlange des GUI-Threads. Wenn sich nun hintereinander soviele solcher Nachrichten in der Nachrichtenschlange angesammelt haben, dass deren Abarbeitung in der Summe länger 1/10s dauert, blockiert das GUI genauso, als wäre nur eine Nachricht eingestellt worden, deren Verarbeitung länger als 1/10s dauert.

Es ist also keineswegs so, dass Control.BeginInvoke in jedem Fall besser ist als Control.Invoke, z.B. wenn sowieso gleichzeitige Zugriffe auf die gemeinsamen Daten verhindert werden müssen. Und es ist keineswegs so, dass man mit der Umstellung von Control.Invoke auf Control.BeginInvoke alle Probleme löst. Wenn sehr viele Events gefeuert werden, kann es nötig sein, diese ohne Control.Invoke/Control.BeginInvoke erstmal nur zu sammeln und das GUI regelmäßig per Timer zu aktualisieren.

Aber davon mal abgesehen ist der Vorschlag von FZelle eine erwägenswerte Alternative zu der Verwendung von Events. Events sind praktisch, keine Frage, aber ein Logging, das direkt oder per AOP in den eigentlichen Bearbeitungscode integriert ist, hat auch seine Vorteile. Insbesondere wenn man später das Ziel des Loggings ändern will und nicht mehr ins GUI, sondern z.B. in eine Datei - oder sagen wir über eine IPC-Verbindung in eine separate Anwendung, die die Meldungen anzeigt - geloggt werden soll, ist es gar nicht nötig bzw. sogar gar nicht wünschenswert, wenn das GUI involviert ist.

herbivore

T
torti Themenstarter:in
193 Beiträge seit 2006
vor 11 Jahren

danke an allen!

torti