Skip to Content
DocsClientsDotnetProcessesProzess-Verwaltung

Prozess-Verwaltung

Der ProcessDefinitionsClient und ProcessInstancesClient bieten umfassende Funktionen zur Verwaltung von BPMN-Prozessen und deren Instanzen.

Überblick

Die Prozess-Verwaltung umfasst folgende Hauptfunktionen:

ProcessDefinitionsClient

ProcessInstancesClient

Client erstellen

ProcessDefinitionsClient

using ProcessCube.Engine; var engineAddress = "http://localhost:8000"; var client = ClientFactory.CreateProcessDefinitionsClient(engineAddress);

ProcessInstancesClient

using ProcessCube.Engine; var engineAddress = "http://localhost:8000"; var client = ClientFactory.CreateProcessInstancesClient(engineAddress);

Schnellstart-Beispiel

Ein komplettes Beispiel vom Deployen bis zum Starten eines Prozesses:

using ProcessCube.Engine; var engineAddress = "http://localhost:8000"; // Clients erstellen var definitionsClient = ClientFactory.CreateProcessDefinitionsClient(engineAddress); var instancesClient = ClientFactory.CreateProcessInstancesClient(engineAddress); // 1. BPMN-Datei laden var bpmnXml = await File.ReadAllTextAsync("OrderProcess.bpmn"); // 2. Prozess deployen await definitionsClient.UploadProcessDefinitionAsync( bpmnXml, overwriteExisting: true ); Console.WriteLine("Prozess erfolgreich deployed"); // 3. Prozess starten var payload = new OrderPayload( OrderId: "ORD-12345", CustomerName: "Max Mustermann", Amount: 1500.00m ); var startResponse = await definitionsClient.StartProcessInstanceAsync( processModelId: "OrderProcess", startEventId: "StartEvent_1", initialToken: payload ); Console.WriteLine($"Prozess gestartet: {startResponse.ProcessInstanceId}"); // 4. Status prüfen var instances = await instancesClient.QueryAsync(query => { query.FilterByProcessInstanceId(startResponse.ProcessInstanceId); }); var instance = instances.Single(); Console.WriteLine($"Status: {instance.State}"); // Payload-Definition internal sealed record OrderPayload( string OrderId, string CustomerName, decimal Amount );

Verwenden Sie C# Records für typisierte Prozess-Payloads. Dies ermöglicht Type Safety und IntelliSense-Unterstützung.

Prozess-Lifecycle

Ein typischer Prozess-Lifecycle mit dem .NET Client:

using ProcessCube.Engine; using ProcessCube.Engine.ProcessInstances; var engineAddress = "http://localhost:8000"; var definitionsClient = ClientFactory.CreateProcessDefinitionsClient(engineAddress); var instancesClient = ClientFactory.CreateProcessInstancesClient(engineAddress); // 1. Prozess deployen var bpmnXml = await File.ReadAllTextAsync("ApprovalProcess.bpmn"); await definitionsClient.UploadProcessDefinitionAsync(bpmnXml, overwriteExisting: true); // 2. Prozess starten var startPayload = new ApprovalRequest( RequestId: "REQ-789", Type: "Budget", Amount: 50000.00m, Requestor: "alice@company.com" ); var response = await definitionsClient.StartProcessInstanceAsync( processModelId: "ApprovalProcess", startEventId: "StartEvent_1", initialToken: startPayload ); var processInstanceId = response.ProcessInstanceId; Console.WriteLine($"Approval-Prozess gestartet: {processInstanceId}"); // 3. Status überwachen await MonitorProcessAsync(instancesClient, processInstanceId); async Task MonitorProcessAsync( IProcessInstancesClient client, string instanceId) { while (true) { var instances = await client.QueryAsync(query => { query.FilterByProcessInstanceId(instanceId); }); var instance = instances.SingleOrDefault(); if (instance == null) { Console.WriteLine("Prozess-Instanz nicht gefunden"); break; } Console.WriteLine($"Status: {instance.State}"); // Prüfen ob Prozess beendet ist if (instance.State == ProcessState.Finished) { Console.WriteLine("Prozess erfolgreich abgeschlossen"); break; } else if (instance.State == ProcessState.Error) { Console.WriteLine("Prozess mit Fehler beendet"); break; } else if (instance.State == ProcessState.Terminated) { Console.WriteLine("Prozess wurde abgebrochen"); break; } // 5 Sekunden warten await Task.Delay(5000); } } // Payload-Definition internal sealed record ApprovalRequest( string RequestId, string Type, decimal Amount, string Requestor );

ProcessState Enum

Prozess-Instanzen können folgende States haben:

StateBeschreibung
RunningProzess läuft aktuell
SuspendedProzess wartet (z.B. auf User Task)
FinishedProzess erfolgreich beendet
ErrorProzess mit Fehler beendet
TerminatedProzess wurde manuell abgebrochen

Best Practices

1. Typisierte Payloads verwenden

// ✅ Empfohlen - Type Safe mit Record internal sealed record OrderPayload( string OrderId, string CustomerName, decimal Amount ); var payload = new OrderPayload("ORD-123", "Max Mustermann", 1500.00m); await client.StartProcessInstanceAsync("OrderProcess", "StartEvent_1", payload); // ❌ Nicht empfohlen - Anonymes Objekt await client.StartProcessInstanceAsync( "OrderProcess", "StartEvent_1", new { orderId = "ORD-123", customerName = "Max Mustermann" } );

2. Fehlerbehandlung implementieren

using ProcessCube.Engine.Client.Exceptions; try { var response = await client.StartProcessInstanceAsync( processModelId: "OrderProcess", startEventId: "StartEvent_1", initialToken: payload ); } catch (EngineClientException ex) when (ex.StatusCode == 404) { Console.WriteLine("Prozess wurde nicht gefunden"); } catch (EngineClientException ex) when (ex.StatusCode == 401) { Console.WriteLine("Nicht authentifiziert"); } catch (HttpRequestException ex) { Console.WriteLine($"Verbindungsfehler: {ex.Message}"); }

3. Async/Await korrekt verwenden

// ✅ Empfohlen - Async/Await var instances = await client.QueryAsync(query => { query.FilterByProcessModelId("OrderProcess"); }); // ❌ Nicht empfohlen - Blockierender Call var instances = client.QueryAsync(query => { query.FilterByProcessModelId("OrderProcess"); }).Result; // Kann zu Deadlocks führen

Verwenden Sie niemals .Result oder .Wait() auf async Tasks, da dies zu Deadlocks führen kann. Nutzen Sie immer await.

Dependency Injection

Integration in ASP.NET Core:

// Program.cs oder Startup.cs public void ConfigureServices(IServiceCollection services) { var engineAddress = Configuration["ProcessCube:EngineAddress"]; // Clients als Singletons registrieren services.AddSingleton<IProcessDefinitionsClient>(sp => ClientFactory.CreateProcessDefinitionsClient(engineAddress) ); services.AddSingleton<IProcessInstancesClient>(sp => ClientFactory.CreateProcessInstancesClient(engineAddress) ); } // Controller public class OrderController : ControllerBase { private readonly IProcessDefinitionsClient _definitionsClient; private readonly IProcessInstancesClient _instancesClient; public OrderController( IProcessDefinitionsClient definitionsClient, IProcessInstancesClient instancesClient) { _definitionsClient = definitionsClient; _instancesClient = instancesClient; } [HttpPost("orders")] public async Task<IActionResult> CreateOrder([FromBody] OrderDto order) { var payload = new OrderPayload( order.OrderId, order.CustomerName, order.Amount ); var response = await _definitionsClient.StartProcessInstanceAsync( processModelId: "OrderProcess", startEventId: "StartEvent_1", initialToken: payload ); return Ok(new { processInstanceId = response.ProcessInstanceId }); } }

Nächste Schritte

Erkunden Sie die einzelnen Themen: