Skip to main content

Run a Worker - .NET SDK

View Markdown

This page covers long-lived Workers that you host and run as persistent processes. For Workers that run on serverless compute like AWS Lambda, see Serverless Workers.

Create and run a Worker

Create a TemporalWorker with a Temporal Client and a TemporalWorkerOptions that names the Task Queue to poll. Add the Workflows and Activities the Worker can execute, then call ExecuteAsync() to start polling.

features/snippets/worker/worker.cs

var options = new TemporalWorkerOptions("my-task-queue");
options.AddWorkflow<GreetingWorkflow>();
options.AddAllActivities(typeof(GreetingActivities), null);

using var worker = new TemporalWorker(client, options);
await worker.ExecuteAsync(CancellationToken.None);

ExecuteAsync() takes a CancellationToken and polls until that token is cancelled. The snippet passes CancellationToken.None, which never cancels, so the Worker runs until the process exits. To stop a Worker on demand, pass a token you control instead. See Shut down a Worker.

TemporalWorker implements IDisposable, so declare it with using to release its resources when the process exits.

Register Workflows and Activities

All Workers polling the same Task Queue must register the same Workflow Types and Activity Types. A Task Queue does not route by type, so any Worker polling it can receive any Task on that queue. A Worker that receives a Task for a type it did not register fails that Task.

Add Workflows with AddWorkflow<T>() and Activities with AddActivity() or AddAllActivities():

var options = new TemporalWorkerOptions("my-task-queue");
options.AddWorkflow<GreetingWorkflow>();
options.AddWorkflow<OrderWorkflow>();
options.AddAllActivities(new MyActivities(databaseClient));

AddAllActivities() registers every method marked with [Activity]. Pass an instance to register instance methods, which lets Activities share state such as a database client. For a class of static Activity methods, pass the type and null instead.

Connect to Temporal Cloud

To run a Worker against Temporal Cloud, configure the Client connection with your Namespace address and authentication credentials. See Connect to Temporal Cloud for setup instructions.

Configure Worker options

TemporalWorkerOptions controls concurrency limits, pollers, timeouts, and caching, including MaxConcurrentActivities, MaxConcurrentWorkflowTasks, and MaxCachedWorkflows. The defaults work for most cases.

To tune these values against real load, see Worker performance and the Worker tuning reference.

Run a versioned Worker

Set a Worker Deployment Version and enable versioning in DeploymentOptions, then set a versioning behavior on each Workflow.

features/snippets/worker/worker.cs

var options = new TemporalWorkerOptions("my-task-queue")
{
DeploymentOptions = new WorkerDeploymentOptions(
new WorkerDeploymentVersion("my-app", "1.0"),
useWorkerVersioning: true),
};
options.AddWorkflow<VersionedGreetingWorkflow>();
options.AddAllActivities(typeof(GreetingActivities), null);

using var worker = new TemporalWorker(client, options);

Set the behavior per Workflow with [Workflow(VersioningBehavior = VersioningBehavior.Pinned)], or set a default for the whole Worker with DefaultVersioningBehavior on WorkerDeploymentOptions. VersioningBehavior comes from the Temporalio.Common namespace.

A versioning behavior applies only to a Worker that has versioning enabled. If a Workflow declares one and its Worker does not enable versioning, the server rejects the Workflow Task and the Task retries instead of failing outright.

See Worker Versioning for the available versioning behaviors and how new versions roll out.

Shut down a Worker

To stop a Worker on demand, start it with a token you can cancel yourself instead of CancellationToken.None. Create a CancellationTokenSource, pass its Token to ExecuteAsync(), then cancel the source when the Worker should stop, such as from a Console.CancelKeyPress handler. The Worker stops polling for new Tasks and waits for in-flight Tasks to finish, up to GracefulShutdownTimeout.

features/snippets/worker/worker.cs

using var tokenSource = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
tokenSource.Cancel();
eventArgs.Cancel = true;
};

var options = new TemporalWorkerOptions("my-task-queue")
{
GracefulShutdownTimeout = TimeSpan.FromSeconds(30),
};
options.AddWorkflow<GreetingWorkflow>();

using var worker = new TemporalWorker(client, options);
await worker.ExecuteAsync(tokenSource.Token);

ExecuteAsync() throws OperationCanceledException once the Worker stops, so catch it where you want the process to exit cleanly. See Worker shutdown for what happens to in-flight Workflow Tasks and Activities.