www.rolandk.de
- Aktuelle Themen zu .Net -
Achtung: Hier handelt es sich um meine alte Seite.
Die aktuelle ist unter folgendem Link erreichbar: www.rolandk.de/wp/
Home Blog Großer Overhead beim Debuggen von Workflows




















































Großer Overhead beim Debuggen von Workflows
Sonntag, den 24. Juli 2011 um 15:40 Uhr

Aktuell experimentiere ich mit der Workflow Foundation 4 (.Net Framework 4.0, Namespace System.Activities). Einer der ersten Punkte, die ich mir angeschaut habe, war die Performance. Ganz klar, erzeugt das Framework hier zu viel Overhead, so ist es nicht wirklich interessant für mich. Eines meiner ersten Testprogramme hatte also etwa folgenden Aufbau:

  1. //Record some more calls in one bundle
  2. stopwatch.Start();
  3. {
  4. for (int loop = 0; loop < bundleCallCount; loop++)
  5. {
  6. workflowInvoker.Invoke(inputs);
  7. }
  8. }
  9. stopwatch.Stop();
  10. double millisBundleCalls = stopwatch.Elapsed.TotalMilliseconds;

Die Variable bundleCallCount hatte dabei den Wert 1000. Nach erfolgter Codierung habe ich dann einfach wie immer per F5 (Starten und Debuggen) gestartet und einen Haltepunkt am Ende des Programmes gesetzt, damit ich direkt den Wert von millisBundleCall auslesen kann. Bis der Haltepunkt erreicht wurde, verging überraschenderweise sehr viel Zeit und ein Blick auf das Ausgabefenster hat mir auch offenbart, warum.

 

 

Für jeden Aufruf von WorkflowInvoker.Invoke wird für die Laufzeit des Workflows ein Thread gestartet und dann gleich wieder beendet. Was aber noch schlimmer ist: Bei jedem Invoke wird zusätzlich eine neue dynamische Assembly geladen, obwohl es sich immer um den selben Workflow handelt. Mein erster Gedanke war klar: So bringt mir das Framework nichts. Die Ursache hinter diesem Verhalten liegt aber nicht in einem Fehler im Framework oder Ähnlichem, sondern schlicht beim Debugger. Und zwar erzeugt die Workflow Foundation eine zusätzliche Assembly zusammen mit der entsprechenden Symboldatei - sofern der Prozess von einem Debugger überwacht wird. Führt man das Programm ohne Debugger aus, so ist die Performance absolut in Ordnung und es wird auch nicht für jeden Invoke eine neue Assembly erzeugt.

 

Die Frage, die sich mir noch gestellt hat, ist folgende: Kann man das abschalten? Zwar ist klar, dass ich beim Debuggen auch hin und wieder direkt in Workflows rein debuggen möchte, aber halt nun mal nicht immer. Und der Performanceverlusst ist auch nicht gerade gering. Nach einer etwas längeren Suche habe ich schließlich mit dem Programm ILSpy nachfolgende Stelle im Quellcode der Workflow Foundation gefunden:

  1. private bool IsDebugged()
  2. {
  3. if (this.debugController == null &amp;&amp; Debugger.IsAttached)
  4. {
  5. this.debugController = new DebugController(this.host);
  6. }
  7. return this.debugController != null;
  8. }

Das heißt, es gibt kein Flag o. Ä., das dieses Verhalten deaktivieren kann. Es hängt rein davon ab, ob der Prozess während des Invoke-Aufrufs von einem Debugger überwacht wird. Die Klasse, in der sich diese Methode befindet, ist übrigens die System.Activities.Runtime.ActivityExecutor Klasse.

 

Kommentar hinzufügen

Ihr Name:
Kommentar: