Einstieg zur Workflow Foundation 4 : WorkflowApplication als erweiterter Workflow Hoster

by Gregor Biswanger 15. Dezember 2010 09:06

Das die Klasse WorkflowInvoker als Workflow Hoster fungiert ist bereits bekannt. Jedoch handelt es sich hierbei um einen leichtgewichtigen Workflow Hoster, womit Workflows Synchron und Asynchron ausgeführt werden können. Was jedoch wenn man direkten Einfluss außerhalb auf Workflows ausüben möchte? oder auf bestimmte Situationen dementsprechend Logik hinterlegen möchte?

Dazu dient die Klasse WorkflowApplication. Die einen etwas umfangreicheren Workflow Hoster entspricht. Diese kann zum Gegenteil der abgespeckten WorkflowInvoker Version:

 

  1. Erstellen einer neuen Workflowinstanz oder Laden einer Workflowinstanz aus einem Instanzspeicher
  2. Bereitstellen von Erweiterungen für Aktivitäten in einer Workflowinstanz
  3. Steuern der Ausführung einer Workflowinstanz
  4. Wiederaufnahme eines von einer Aktivität erstellten Lesezeichens in einer Workflowinstanz
  5. Ablegen im Persistenzspeicher/Entladen einer Workflowinstanz
  6. Aktivieren von Benachrichtigungen bei Ereignissen im Workflowinstanzlebenszyklus

 

Zur Demonstration wird das gleiche Beispiel vom Blog-Post “Einstieg zur Workflow Foundation 4 : Workflows asynchron aufrufen” verwendet. Der Source-Code der Program.cs-Datei wird wie unter Listing 1 geändert.

 

   1:   class Program
   2:      {
   3:          private static readonly AutoResetEvent WaitEvent = new AutoResetEvent(false);
   4:   
   5:          static void Main(string[] args)
   6:          {
   7:              Console.WriteLine("Host: Ich starte DemoWorkflow - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
   8:   
   9:              WorkflowApplication workflowApplication = new WorkflowApplication(new DemoWorkflow());
  10:   
  11:   
  12:              workflowApplication.Completed = (e) =>
  13:                                                  {
  14:                                                      switch (e.CompletionState)
  15:                                                      {
  16:                                                          case ActivityInstanceState.Closed:
  17:                                                              Console.WriteLine("Host: Closed - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  18:                                                              break;
  19:                                                          case ActivityInstanceState.Canceled:
  20:                                                              Console.WriteLine("Host: Canceled - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  21:                                                              break;
  22:                                                          case ActivityInstanceState.Executing:
  23:                                                              Console.WriteLine("Host: Executing - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  24:                                                              break;
  25:                                                          case ActivityInstanceState.Faulted:
  26:                                                              Console.WriteLine("Host: Faulted - Thread: {0} - {1}:{2}", Thread.CurrentThread.ManagedThreadId,
  27:                                                                                                                                                          e.TerminationException.GetType(),
  28:                                                                                                                                                          e.TerminationException.Message);
  29:                                                              break;
  30:                                                      }
  31:   
  32:                                                      WaitEvent.Set();
  33:                                                  };
  34:   
  35:              workflowApplication.OnUnhandledException = (e) =>
  36:                                                             {
  37:                                                                 Console.WriteLine("Host: OnUnhandledException - Thread: {0} - {1}", Thread.CurrentThread.ManagedThreadId,
  38:                                                                                                                                                                              e.UnhandledException.Message);
  39:   
  40:                                                                 WaitEvent.Set();
  41:   
  42:                                                                 return UnhandledExceptionAction.Cancel;
  43:                                                             };
  44:   
  45:   
  46:              workflowApplication.Aborted = (e) =>
  47:              {
  48:                  Console.WriteLine("Host: Aborted - Thread: {0} - {1}", Thread.CurrentThread.ManagedThreadId,
  49:                                                                                                                               e.Reason.Message);
  50:   
  51:                  WaitEvent.Set();
  52:              };
  53:   
  54:              workflowApplication.Idle = (e) =>
  55:              {
  56:                  Console.WriteLine("Host: Idle - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  57:              };
  58:   
  59:              workflowApplication.PersistableIdle = (e) =>
  60:              {
  61:                  Console.WriteLine("Host: PersistableIdle - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  62:   
  63:                  return PersistableIdleAction.Unload;
  64:              };
  65:   
  66:              workflowApplication.Unloaded = (e) =>
  67:              {
  68:                  Console.WriteLine("Host: Unloaded - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  69:              };
  70:   
  71:              try
  72:              {
  73:                  workflowApplication.Run();
  74:   
  75:                  Console.WriteLine("Host: DemoWorkflow gestartet... - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  76:                  WaitEvent.WaitOne();
  77:              }
  78:              catch (Exception exception)
  79:              {
  80:                  Console.WriteLine("Host: Exception - {0}", exception.Message);
  81:              }
  82:   
  83:              Console.ReadLine();
  84:          }
  85:      }

Listing 1 – WorkflowApplication als Workflow Hoster

 

Wie bereits beim Source-Code aus Listing 1 ersichtlich ist, wird von der WorkflowApplication eine Instanz erzeugt. Anschließend kann man auf bestimmte Prozesssituationen eine eigene Logik hinterlegen.

Das wären aus dem Beispiel folgende:

Name Beschreibung
Completed Wird beim Abschluss der Workflowinstanz ausgelöst, bzw. legt sie fest.
OnUnhandledException Wird ausgelöst wenn die aktuelle Workflowinstanz eine unbehandelte Ausnahme erkennt, bzw. legt sie fest.
Aborted Wird bei Abbruch der Workflowinstanz ausgelöst, bzw. legt sie fest.
Idle Wird ausgelöst wenn die aktuelle Workflowinstanz in den Leerlauf wechselt, bzw. legt sie fest.
PersistableIdle Wird ausgelöst wenn die aktuelle Workflowinstanz sich im Leerlauf befindet und im Persistenzspeicher abgelegt werden kann.
Unloaded Wird beim Entladen des aktuellen Workflows ausgelöst, bzw. legt sie fest.

Tabelle 1 – Beschreibung der Eigenschaften der WorkflowApplication aus Listing 1

 

Das war allerdings nur ein Teil von Eigenschaften der WorkflowApplication die hierbei verwendet wurden. Wird die Anwendung nun ausgeführt sieht das Ergebnis wie unter Abb. 1 aus.

 

SNAGHTML484a5a8

Abb. 1 – Workflow mittels WorkflowApplication gehostet

 

Einfluss außerhalb

Um nun die Stärke der WorkflowApplication zu verdeutlichen werden von außerhalb der laufenden Workflow-Instanz unterschiedliche Einflüsse durchgeführt.

 

Beenden einer Workflow Instanz

Dazu wird beim Source-Code von Listing 1 ab Zeile 73 folgendes hinzugefügt:

   1:  ...
   2:  try
   3:  {
   4:      workflowApplication.Run();
   5:   
   6:      Thread.Sleep(TimeSpan.FromSeconds(1));
   7:   
   8:      workflowApplication.Cancel();
   9:   
  10:      Console.WriteLine("Host: DemoWorkflow gestartet... - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  11:      WaitEvent.WaitOne();
  12:  }
  13:  catch (Exception exception)
  14:  {
  15:      Console.WriteLine("Host: Exception - {0}", exception.Message);
  16:  }
  17:  ...

Listing 2 – Workflow Instanz wird beendet

Die Cancel-Methode bricht die Workflow Instanz sofort ab. Die Ausgabe ist unter Abb. 2 ersichtlich.

SNAGHTML493eea9

Abb. 2 – Workflow wird nach 1 Sekunde beendet

 

Abbrechen einer Workflow Instanz

Die Abort-Methode benachrichtigt die Workflowlaufzeit, dass diese Workflowinstanz abgebrochen werden soll.

   1:  ...
   2:  try
   3:  {
   4:      workflowApplication.Run();
   5:   
   6:      Thread.Sleep(TimeSpan.FromSeconds(1));
   7:   
   8:      workflowApplication.Abort(“Bitte beenden wenn möglich”);
   9:   
  10:      Console.WriteLine("Host: DemoWorkflow gestartet... - Thread: {0}", Thread.CurrentThread.ManagedThreadId);
  11:      WaitEvent.WaitOne();
  12:  }
  13:  catch (Exception exception)
  14:  {
  15:      Console.WriteLine("Host: Exception - {0}", exception.Message);
  16:  }
  17:  ...

Listing 3 – Workflow Instanz wird abgebrochen

 

Die Ausgabe sieht dann wie folgt aus:

SNAGHTML49ab005

Abb. 3 - Workflow wird nach 1 Sekunde abgebrochen

 

Die Beispiele haben gezeigt wie “einfach” außerhalb mit einer Workflow-Instanz mittels WorkflowApplication umgegangen werden kann.



Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitten "kicken" sie ihn.
kick it on dotnet-kicks.de

Kommentare

Powered by BlogEngine.NET 1.4.5.0
Theme by Extensive SEO

Über den Autor

Gregor Biswanger

Microsoft MVP für Client App Dev
XING

Gregor Biswanger (Microsoft MVP für Client App Dev) ist freier Consultant, Trainer, Autor und Speaker.


Seine Schwerpunkte liegen im Bereich der .NET-Architektur, agilen Prozessen und XAML. Er veröffentlichte vor kurzem seine DVD´s mit Video-Trainings zum Thema „Meine erste Windows 8 App“, „Windows Store Apps mit XAML und C#“ und „WPF 4.5 und Silverlight 5“ bei Addison-Wesley von video2brain.


Biswanger ist auch im Auftrag von Intel GmbH als Technologieberater für die Intel Developer Zone aktiv und ist Leader bei der Ingolstädter .NET Developers Group (INdotNET). 

 

Video über mich:
http://www.youtube.com/watch?v=mx_6SiiLxjk


Basta! 2011 Speaker

CLIPer

MCTS
Windows SharePoint Services 3.0 – Application Development (MCTS)