Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Beim Ausführen eines Workflows in .NET steuert der Ausführungsmodus, wie Supersteps (Super-Schritte) verarbeitet werden und wie Ereignisse an den Verbraucher übermittelt werden. Die InProcessExecution Klasse macht zwei Ausführungsmodi verfügbar: OffThread und Lockstep.
Übersicht
| OffThread (Standard) | Sperrschritt | |
|---|---|---|
| Superstep-Ausführung | Hintergrundthread | Thread des Verbrauchers |
| Ereignisübermittlung | Unmittelbar, wenn Ereignisse ausgelöst werden | Stapelverarbeitung nach Abschluss jedes Supersteps |
| Schrittausführung | Unabhängig von der Ereignisverarbeitung | Angehalten, bis gebündelte Ereignisse verarbeitet werden |
| Parallelität | Consumer liest Ereignisse ein, während Supersteps ausgeführt werden | Wechsel zwischen Consumer- und Superstep-Ausführung |
| Am besten geeignet für | Echtzeitstreaming, Produktionsszenarien | Testen, Debuggen, deterministische Sortierung |
OffThread
OffThread ist der Standardausführungsmodus . Supersteps werden in einem Hintergrundthread ausgeführt, und Ereignisse werden sofort gestreamt, wenn sie über eine kanalbasierte Architektur ausgelöst werden.
// OffThread is the default — these are equivalent:
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input);
await using StreamingRun run = await InProcessExecution.OffThread.RunStreamingAsync(workflow, input);
So funktioniert es
- Eine Hintergrundaufgabe führt fortlaufend Supersteps aus, während Nachrichten ausstehen.
- Wenn Executoren Ausgaben oder Ereignisse liefern, werden die resultierenden
WorkflowEventObjekte in ein ungebundenesChannel<WorkflowEvent>Objekt geschrieben. - Der Konsument liest Ereignisse aus dem Kanal
WatchStreamAsyncund empfängt sie in Echtzeit, sobald sie produziert werden. - Wenn alle Supersteps abgeschlossen sind und keine Nachrichten verbleiben, wird die Ausführung mit einem
IdleoderPendingRequestsStatus angehalten.
Da die Superstep-Schleife und der Consumer parallel laufen, werden Ereignisse sofort angezeigt, sobald sie ausgelöst werden – ohne Verzögerung durch Pufferung. Dies macht OffThread ideal für Streamingszenarien, in denen die Übermittlung von Ereignissen mit geringer Latenz wichtig ist, z. B. das Anzeigen von Token-nach-Token-Updates in einer Benutzeroberfläche.
Parallelausführungen
OffThread unterstützt auch eine gleichzeitige Variante, mit der mehrere Ausführungen dieselbe Workflowinstanz gleichzeitig gemeinsam nutzen können:
await using StreamingRun run = await InProcessExecution.Concurrent.RunStreamingAsync(workflow, input);
Von Bedeutung
Für die gleichzeitige Ausführung müssen alle Ausführenden im Workflow entweder im Konstruktor deklariert oder als Fabrikmethoden bereitgestellt werden.
Sperrschritt
Im Lockstep-Modus werden Supersteps im Thread des Verbrauchers statt auf einer Hintergrundaufgabe ausgeführt. Ereignisse werden während jedes Supersteps gesammelt und nach Abschluss des Supersteps als Batch ausgegeben.
await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);
So funktioniert es
- Der Consumer ruft auf
WatchStreamAsync, was die Ausführungsschleife steuert. - Ein Superstep wird vollständig ausgeführt, und Ereignisse werden in einer Warteschlange gesammelt.
- Nach Abschluss des Supersteps werden alle ausstehenden Ereignisse dem Empfänger übergeben.
- Der nächste Superstep beginnt erst, nachdem der Verbraucher alle Ereignisse aus dem vorherigen empfangen hat.
Dieses abwechselnde Muster bedeutet, dass der Consumer und die Workflow-Engine nie gleichzeitig ausgeführt werden. Die Ereignisübermittlung ist deterministisch – alle Ereignisse aus einem Superstep werden garantiert vor Ereignissen aus dem nächsten Superstep eintreffen.
Wann man Lockstep verwenden sollte
Lockstep ist nützlich, wenn:
- Tests – deterministische Ereignisordnung macht Assertionen einfach.
- Debugging – Schrittweises Debugging ist einfacher, wenn die Ausführung im Thread des Nutzers verbleibt.
- Sortierte Verarbeitung – Szenarien, in denen Sie die Ereignisse eines Supersteps vollständig verarbeiten müssen, bevor der nächste Superstep beginnt.
Auswählen eines Ausführungsmodus
Für die meisten Produktionsszenarien wird der Standardmäßige OffThread-Modus empfohlen. Es bietet die beste Reaktionsfähigkeit und ermöglicht es dem Workflow, die Verarbeitung fortzusetzen, während der Consumer Ereignisse verarbeitet.
Verwenden Sie Lockstep, wenn deterministisches Verhalten wichtiger ist als Leistung, z. B. bei Unit-Tests oder Debugging-Sitzungen.
// Production: OffThread (default)
await using StreamingRun run = await InProcessExecution.RunStreamingAsync(workflow, input);
// Testing: Lockstep for deterministic behavior
await using StreamingRun run = await InProcessExecution.Lockstep.RunStreamingAsync(workflow, input);
Nicht-Streaming-Ausführung
Beide Ausführungsmodi unterstützen die Nicht-Streaming-Ausführung über RunAsync. Im Nicht-Streaming-Modus wird der Workflow zum Abschluss ausgeführt und sammelt alle Ereignisse in einem Run Objekt, anstatt sie inkrementell zu streamen:
Run run = await InProcessExecution.RunAsync(workflow, input);
// Access all emitted events
foreach (WorkflowEvent evt in run.OutgoingEvents)
{
// Process events
}
Da die nicht streamende Ausführung alle Ereignisse nach Abschluss erfasst, gilt der Echtzeitvorteil von OffThread nicht. Der Hauptunterschied zwischen den Modi in Nicht-Streaming-Szenarien liegt im Threading: Bei OffThread werden die Supersteps in einem Hintergrundthread ausgeführt, sodass der aufrufende Thread während des Wartens auf die Fertigstellung freigegeben wird. Im Gegensatz dazu werden bei Lockstep die Supersteps im Thread des Aufrufers ausgeführt und blockieren diesen, bis der Workflow beendet ist.
Bei der Ausführung ohne Streaming wird der Standardmäßige OffThread-Modus verwendet. So verwenden Sie Lockstep mit nicht streamingbasierter Ausführung:
Run run = await InProcessExecution.Lockstep.RunAsync(workflow, input);
Nächste Schritte
Ausführungsmodi gelten nicht für Python-Workflows. Python-Workflows verwenden ein einzelnes Ausführungsmodell, das die Superstep-Verarbeitung und Ereignisübermittlung über einen asynchronen Generator abwickelt. Dieses Modell ähnelt dem .NET Lockstep-Modus – Schritte schreiten nur voran, wenn der Consumer aktiv Ereignisse vom Generator abruft.
Informationen zum Ausführen von Python-Workflows finden Sie unter Workflow Builder & Execution.
Beim Ausführen eines Workflows in Go steuert die Ausführungsumgebung, wie Supersteps verarbeitet werden und wie Ereignisse an den Verbraucher übermittelt werden. Das workflow/inproc Paket macht drei Umgebungen verfügbar: Default/OffThread, , Lockstepund Concurrent.
Übersicht
| OffThread / Standard | Sperrschritt | Konkurrent | |
|---|---|---|---|
| Superstep-Ausführung | Hintergrund-Goroutine | Vom Event-Consumer gesteuert | Hintergrundgoroutine |
| Ereignisübermittlung | Unmittelbar, wenn Ereignisse ausgelöst werden | In Batches, während der Datenstrom verarbeitet wird | Unmittelbar, wenn Ereignisse ausgelöst werden |
| Am besten geeignet für | Echtzeitstreaming, Produktionsszenarien | Testen, Debuggen, deterministische Sortierung | Freigegebene Workflowinstanzen mit gleichzeitig sicheren Bindungen |
OffThread
OffThread ist der Standardausführungsmodus. Dies sind gleichwertig:
stream, err := inproc.Default.RunStreaming(ctx, wf, input)
stream, err := inproc.OffThread.RunStreaming(ctx, wf, input)
So funktioniert es
- Eine im Hintergrund laufende Goroutine führt Supersteps aus, solange noch Nachrichten ausstehen.
- Wenn Executors Ausgaben oder Ereignisse ausgeben, werden Workflow-Ereignisse in den Stream geschrieben.
- Der Verbraucher liest Ereignisse mit
WatchStreamund empfängt sie, während sie produziert werden. - Wenn alle Supersteps abgeschlossen sind und keine Nachrichten mehr vorhanden sind, endet der Lauf mit dem Status „Leerlauf“ oder „Ausstehende Anforderung“.
Parallelausführungen
Verwenden Sie inproc.Concurrent, wenn alle Executor-Bindungen im Workflow die gemeinsame gleichzeitige Ausführung unterstützen:
stream, err := inproc.Concurrent.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer stream.Close(ctx)
Sperrschritt
Im Lockstep-Modus schreitet die Workflow-Ausführung voran, während der Verbraucher aus dem Datenstrom liest. Dadurch wird die Ereignisbestellung für Tests und Debugging deterministisch.
stream, err := inproc.Lockstep.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer stream.Close(ctx)
for evt, err := range stream.WatchStream(ctx) {
if err != nil {
return err
}
// inspect event
}
So funktioniert es
- Der Consumer ruft auf
WatchStream, was die Ausführungsschleife steuert. - Ein Superstep wird bis zum Abschluss ausgeführt, und Ereignisse werden akkumuliert.
- Die akkumulierten Ereignisse werden an den Consumer übergeben.
- Der nächste Superstep beginnt erst, nachdem der Verbraucher die Ereignisse des vorherigen Supersteps erhält.
Wann man Lockstep verwenden sollte
Verwenden Sie Lockstep, wenn deterministisches Verhalten mehr als das Streaming mit geringer Latenz wichtig ist, z. B. Komponententests, Debugging oder Szenarien, in denen Sie die Ereignisse eines Supersteps vollständig verarbeiten möchten, bevor der nächste Superstep beginnt.
Auswählen eines Ausführungsmodus
Für die meisten Produktionsszenarien verwenden inproc.Default oder inproc.OffThread. Verwenden Sie inproc.Lockstep, wenn die deterministische Ereignisreihenfolge wichtiger ist als die Streaminglatenz, z. B. in Tests. Verwenden Sie inproc.Concurrent nur, wenn jede Bindung im Workflow die gemeinsame gleichzeitige Ausführung unterstützt.
// Production: OffThread (default)
stream, err := inproc.Default.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer stream.Close(ctx)
// Testing: Lockstep for deterministic behavior
testStream, err := inproc.Lockstep.RunStreaming(ctx, wf, input)
if err != nil {
return err
}
defer testStream.Close(ctx)
Nicht-Streaming-Ausführung
Alle Ausführungsumgebungen unterstützen auch den Nicht-Streaming-Modus Run, der bis zum nächsten Halt ausgeführt wird und die ausgegebenen Ereignisse im zurückgegebenen Ausführungslauf speichert.
run, err := inproc.Default.Run(ctx, wf, input)
if err != nil {
return err
}
for evt := range run.NewEvents() {
if output, ok := evt.(workflow.OutputEvent); ok {
fmt.Printf("Final result: %v\n", output.Output)
}
}