Der Work-Manager ist über Api.Worker. erreichbar.

Work-Item erzeugen oder aktualisieren

bool CreateOrUpdate(WorkItemBase item, Session session = null)

Die Methode erstellt ein neues Work-Item oder verändert es. Das Work-Item muss vorher mit new erzeugt worden sein. Beispiel:

Api.Worker.CreateOrUpdate(new UpdateRecordCollection(collection, recordGuids, UpdateRecordCollection.WorkType.Add));

Optional kann einen XPO-Session angegeben werden, unter der der Datenbankzugriff erfolgen soll. Wenn dieses eine UnitOfWork ist, dann erfolgt die Einplanung bzw. Änderung erst, wenn für diese CommitChanges aufgerufen wird. Auf diese Weise können auch mehrere Work-Items atomar verändert werden. Das ist im Besonderen beim Einplanen von Nachfolgern wichtig, damit die Kette niemals abreißen kann.

Nach einer erfolgreichen Erstellung oder Aktualisierung hat der Work-Manager im übergebenen Work-Item das Feld Oid ausgefüllt. Der Wert ändert sich auch bei jeder Aktualisierung. Ob genau diese Instanz jemals ausgeführt wird, ist aber nicht gesichert, denn es könnten ja noch weitere Updates folgen.

Aktualisierungen

Wenn fur ein bereits geplantes Work-Item CreateOrUpdate aufgerufen wird – maßgeblich ist die gleiche InstanceGuid – dann gewinnt immer nur der letzte Aufruf.
Maßgeblich ist der Zeitpunkt des Datenbank-Commits.

Es ist zulässig, beim Aktualisieren eines Work-Items wirklich alle Eigenschaften zu ändern. Dazu zählt auch, dass die Implementierende Klasse jetzt eine komplett andere sein kann. Entscheidend ist nur die InstanceGuid.

Nachfolger

Falls es sich um ein wiederkehrendes Work-Item handelt, muss in WorkItemFinished der Nachfolger eingeplant werden, ggf. mit aktualisierten Parametern. Üblicherweise geschieht das über die Methode WorkItemBase.AddSuccessor, CreateOrUpdate würde aber auch funktionieren.

Es können auch beliebige andere Work-Items (Folgeprozesse) mit anderen Instance-Guids in WorkItemFinished als Nachfolger eingeplant werden, auch mehrere.

Laufendes oder geplantes Work-Item abbrechen

EnumWorkItemState StopExecutionOfWorkItem(Guid instanceGuid, bool cancelRunning = true)

Mit dieser Methode kann ein bereits eingeplantes oder laufendes Work-Item abgebrochen werden. Wenn cancelRunning = false ist, wird der Abbruch nur ausgeführt, wenn das Work-Item noch nicht läuft.

  • Wenn das Work-Item noch nicht gestartet wurde, wird die Methode WorkItemFinished mit Status Removed aufgerufen.
    Das schließt auch den Fall ein, dass das Work-Item zwar schon bereit zur Ausführung war, aber noch keinen freien Prozess bekommen hat.
  • Wenn das Work-Item schon läuft, wird der Status asynchron auf CancellingByUser gesetzt und es bekommt ein Signal (WorkItemShouldFinish). Darauf sollte es reagieren und sich binnen einer Minute beenden (Run-Methode kehrt zurück). Danach wechselt der Status auf Cancelled.

Als Rückgabewert erhält man den vorherigen Status des Work-Items oder null, wenn kein geplantes oder laufendes Work-Item mit dieser instanceGuid gefunden wurde.
Aus dem vorherigen Status geht auch hervor, was tatsächlich passiert ist.

Kategorie Status neuer Status Aktion
Waiting alle Removing Die Einplanung des Work-Items wurde widerrufen.
WaitingForPredecessor
Ready Queued
Removing unverändert keine (redundanter Aufruf von StopExecutionOfWorkItem)
Active Running CancellingByUser Abbruch-Signal gesendet.
ShutdownRequest
CancellingBySystem
Abbruch-Signal aktualisiert.
Der Abbruch kam während eines Anwendungsneustarts oder eines Timeouts. Ersteres hat aber Priorität.
Deshalb wird der Status auf CancellingByUser aktualisiert, was im Besonderen einen Neustart des Work-Items verhindert.
CancellingByUser unverändert keine (redundanter Aufruf von StopExecutionOfWorkItem)
Final
Restarted
alle unverändert keine (Beendete Prozesse können nicht mehr abgebrochen werden.)

Der Abbruch selbst erfolgt immer asynchron. Das bedeutet, wenn die Methode zurückkehrt, ist der Abbruch i.a. noch nicht vollzogen. Allerdings ist der Status schon geändert und ggf. sind die Fortschrittsanzeigen informiert.

Normalerweise sollte die Methode nur aufgerufen werden, wenn das Work-Item IsCancellable = true hat. Dies wird aber nicht überprüft. Es obliegt dem Work-Item, was es in diesem Fall macht. Den Abbruch bevor es gestartet wurde, kann es aber nicht verhindern. Es könnte sich allenfalls in WorkItemFinished neu einplanen.

Informationen über Work-Items

Der Status eines Work-Items wird durch die Klasse WorkItemProgress repräsentiert. Diese Informationen entstammen vollständig den nicht serialisierten Spalten aus OrmWorkItem und sind von außen nur lesbar.

Der Status eines Work-Items ist immer transient. Bei allen nicht-abgeschlossenen Work-Items können sich die Werte jederzeit ändern. Mit technischen Exceptions (Data Race) muss man beim Lesen der Eigenschaften aber nicht rechnen.

Liste von Work-Items

List<WorkItemProgress> GetWorkItems(IEnumerable<EnumWorkItemStateCategory> categories, Guid user = default, ICollection<Guid> instanceGuids = null)

Mit obiger Methode können Informationen zu allen im System noch verfügbaren Work-Items abgerufen werden. Das umfasst auch historische (beendete) Work-Items, sofern diese noch nicht vom CleanUpWorkItems Task aufgeräumt wurden.

Das Ergebnis der Funktion ist eine Liste der passenden Work-Items nach aktuellem Stand. Aufgrund der transienten Natur von Work-Items kann sich der Status aber jederzeit ändern. Deshalb muss man auch bei einer Abfrage auf nur laufende Work-Items in Einzelfällen mit einem (gerade erreichten) finalen Status rechnen.

Paremeter categories

Die folgende Liste gibt an, welche Statuskategorien abgefragt werden sollen. Zur Auswahl stehen:

  • EnumWorkItemStateCategory.Waiting Alle Work-Items, die noch nicht bereit zur Ausführung sind.
  • EnumWorkItemStateCategory.Ready Alle Work-Items, die bereit zur Ausführung sind, aber noch nicht zum Zuge kamen, weil nicht genug Prozess-Ressourcen zur Verfügung stehen. Das schließt auf Work-Items ein, die vor dem Start abgebrochen wurden, aber noch keine Gelegenheit hatten, darauf zu reagieren.
  • EnumWorkItemStateCategory.Active Alle laufenden Work-Items einschließlich derer, die ein Abbruch-Signal bekommen, sich daraufhin aber noch nicht beendet haben.
  • EnumWorkItemStateCategory.Final Alle Work-Items, die abgeschlossen sind, einschließlich abgebrochener, fehlerhafter etc.
  • EnumWorkItemStateCategory.Restared Alle Work-Items, die abgeschlossen sind und danach neu eingeplant wurden, egal warum.

Wenn null übergeben wird, werden alle Kategorien abgefragt.

Bei Abfrage der finalen Katergorien Final und/oder Restarted können mehrerer, bereits ausgeführte Worker-Instanzen mit derselben InstanceGuid zurückgeliefert werden. In allen anderen Fällen ist die InstanceGuid eindeutig.

Parameter user

Wenn dieser Parameter nicht initial ist, werden nur Work-Items, die für den angegebenen User (typischerweise der aktuelle User) sichtbar sind zugückgeliefert. Das sind neben seinen eigenen auch alle mit IsVisibleForAllUsers.

Mit den Standardwert default werden immer alle Work-Items unabhängig von ihrem User zurückgeliefert.

Parameter instanceGuids

Hiermit können mehrere InstanceGuids auf einmal abgefragt werden. Die anderen Filter-Parameter greifen aber zusätzlich.
Der Standardwert null bewirkt keine Einschränkung.

Beispiel:

Api.Worker.GetWorkItems(new[] { EnumWorkItemStateCategory.Waiting, EnumWorkItemStateCategory.Ready, EnumWorkItemStateCategory.Active }, UserHelper.CurrentUserGuid())

Information über ein einzenes Work-Item

WorkItemProgress GetWorkItem(Guid instanceGuid)

Mit dieser Methode kann ein einzelnes Work-Item abgefragt werden. Da die InstanceGuid nur für aktuelle Work-Items eindeutig ist, können damit keine abgeschlossenen Work-Items abgefragt werden, sondern nur laufende oder zukünftige. Bei abgeschlossenen (ohne Nachfolger) kommt null.