Skip to content

Signals

Signals let the outside world talk to a running workflow: a human approval, a webhook, a payment confirmation. The workflow parks until the signal arrives, and signals are persisted so nothing is lost across restarts.

[Workflow("approval")]
public sealed class ApprovalWorkflow
{
[WorkflowRun]
public async ValueTask<string> RunAsync(
IWorkflowContext ctx,
string request,
CancellationToken cancellationToken
)
{
var decision = await ctx.WaitForSignal<ApprovalDecision>("approval", cancellationToken);
return decision.Approved ? $"{request} approved." : $"{request} rejected.";
}
}

Send through the handle you got when starting the workflow, or through the client with a run id:

await handle.SignalAsync(
"approval",
new ApprovalDecision(Approved: true, UserId: "era", Comment: "Ship it"),
idempotencyKey: $"approval:{handle.WorkflowRunId:N}"
);