This guide walks you through creating your first Durable Task Framework (DTFx) orchestration.
In this quickstart, you'll create:
- An activity that performs a simple greeting
- An orchestration that calls the activity
- A host that runs the orchestration
dotnet new console -n HelloDurableTask
cd HelloDurableTaskFor this quickstart, we'll use the in-memory emulator:
dotnet add package Microsoft.Azure.DurableTask.Core
dotnet add package Microsoft.Azure.DurableTask.Emulator💡 For production, see Choosing a Backend to select an appropriate provider.
Activities are the basic unit of work in DTFx. Create a file named GreetActivity.cs:
using DurableTask.Core;
public class GreetActivity : TaskActivity<string, string>
{
protected override string Execute(TaskContext context, string name)
{
return $"Hello, {name}!";
}
}Orchestrations coordinate activities. Create a file named GreetingOrchestration.cs:
using DurableTask.Core;
public class GreetingOrchestration : TaskOrchestration<string, string>
{
public override async Task<string> RunTask(OrchestrationContext context, string input)
{
// Call the GreetActivity
string greeting = await context.ScheduleTask<string>(typeof(GreetActivity), input);
return greeting;
}
}Update Program.cs to create and run the orchestration:
using DurableTask.Core;
using DurableTask.Emulator;
using Microsoft.Extensions.Logging;
// Create logger factory for diagnostics
using ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Information);
});
// Create the in-memory orchestration service
var service = new LocalOrchestrationService();
// Create and configure the worker
var worker = new TaskHubWorker(service, loggerFactory);
worker.AddTaskOrchestrations(typeof(GreetingOrchestration));
worker.AddTaskActivities(typeof(GreetActivity));
// Start the worker
await worker.StartAsync();
Console.WriteLine("Worker started.");
// Create a client to start orchestrations
var client = new TaskHubClient(service, loggerFactory: loggerFactory);
// Start a new orchestration instance
var instance = await client.CreateOrchestrationInstanceAsync(
typeof(GreetingOrchestration),
"World");
Console.WriteLine($"Started orchestration: {instance.InstanceId}");
// Wait for completion
var result = await client.WaitForOrchestrationAsync(
instance,
TimeSpan.FromSeconds(30));
Console.WriteLine($"Result: {result.Output}");
Console.WriteLine($"Status: {result.OrchestrationStatus}");
// Stop the worker
await worker.StopAsync();dotnet runExpected output:
Worker started.
Started orchestration: <guid>
Result: "Hello, World!"
Status: Completed
public class GreetActivity : TaskActivity<string, string>TaskActivity<TInput, TOutput>— Base class for activities- Activities contain the actual work logic
- They are automatically retried on failure (configurable)
public class GreetingOrchestration : TaskOrchestration<string, string>TaskOrchestration<TResult, TInput>— Base class for orchestrations- Orchestrations coordinate activities and sub-orchestrations
- They must be deterministic
await context.ScheduleTask<string>(typeof(GreetActivity), input);OrchestrationContextprovides APIs for scheduling workScheduleTask— Schedule an activityCreateSubOrchestrationInstance— Start a sub-orchestrationCreateTimer— Create a durable timerWaitForExternalEvent— Wait for an external event
TaskHubWorker— Hosts orchestrations and activitiesTaskHubClient— Starts and manages orchestration instances
- Choosing a Backend — Select a production-ready provider
- Core Concepts — Understand Task Hubs, Workers, and Clients
- Writing Orchestrations — Learn orchestration patterns
- Writing Activities — Learn activity patterns
- Samples Catalog — Explore more examples