Files
Donald Pinckney 44eba4e91c Add .NET SDK support to temporal-developer skill (#39)
* Add .NET reference files for temporal-developer skill

Created 11 .NET reference files covering: dotnet.md (overview/quick start),
patterns.md, determinism.md, determinism-protection.md, error-handling.md,
testing.md, versioning.md, observability.md, data-handling.md, gotchas.md,
and advanced-features.md. Follows Python/TypeScript patterns with .NET-specific
content for Task determinism, CancellationToken, dependency injection, etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix .NET alignment issues from self-review

- dotnet.md: Reduce Determinism Rules section to brief cross-reference
  (was duplicating determinism.md content)
- patterns.md: Add ParentClosePolicy to Child Workflows example
- gotchas.md: Add missing "Heartbeat Timeout Too Short" subsection
- versioning.md: Add missing Key Concepts, Deployment Strategies,
  Query Filters, PINNED/AUTO_UPGRADE guidance, CLI examples
- advanced-features.md: Add worker-level heading for exception types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix .NET correctness issues from verification pass

- patterns.md: Fix cancellation pattern to use official
  TemporalException.IsCanceledException(e) with detached CancellationTokenSource
- advanced-features.md: Fix DI hosting example to use official
  AddHostedTemporalWorker(clientTargetHost:, clientNamespace:, taskQueue:) pattern

Verified against official SDK README, API docs, and temporal-docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update supported language references to include .NET

- SKILL.md: Add "Temporal .NET" and "Temporal C#" trigger phrases,
  update overview to mention .NET, add .NET entry in getting started
- core/determinism.md: Add .NET entry in SDK Protection Mechanisms

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Edits to advanced features

* edits to determinism protection, and move the .editorconfig section

* missed one

* edit determinism.md

* edit error-handling.md

* edit gotchas.md

* edit patterns.md

* edit versioning.md

* edit observability.md

* fix metrics

* self-review round 1

* minor correctness fixed

* Update references/dotnet/patterns.md

Co-authored-by: Justin Anderson <44687433+jmaeagle99@users.noreply.github.com>

* address comments, clarify reference to earlier code snippet

* clarify that operations are forbidden IN WORKFLOWS

* cleanup workflow cancellation handling example

* add task token retrieval comment

* update .net requirements

* Fix propagation of workflow cancellation

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Justin Anderson <44687433+jmaeagle99@users.noreply.github.com>
2026-04-17 14:28:02 -04:00

2.6 KiB

.NET SDK Determinism

Overview

The .NET SDK has NO runtime sandbox (unlike Python/TypeScript). Workflows must be deterministic for replay, and determinism is enforced by developer convention and runtime task detection via an EventListener (see references/dotnet/determinism-protection.md).

Why Determinism Matters: History Replay

Temporal provides durable execution through History Replay. When a Worker restores workflow state, it re-executes workflow code from the beginning. This requires the code to be deterministic. See references/core/determinism.md for a deep explanation.

Forbidden Operations in Workflows

The following are forbidden inside workflow code but are appropriate to use in activities.

// DO NOT do these in workflows:
await Task.Run(() => { });              // Uses default scheduler
await Task.Delay(TimeSpan.FromSeconds(1)); // System timer
var now = DateTime.UtcNow;              // System clock
var r = new Random().Next();            // Non-deterministic
var id = Guid.NewGuid();               // Non-deterministic
File.ReadAllText("file.txt");           // I/O
await httpClient.GetAsync("...");       // Network I/O

Most non-determinism and side effects should be wrapped in Activities.

Safe Builtin Alternatives

Forbidden Safe Alternative
DateTime.Now / DateTime.UtcNow Workflow.UtcNow
Random Workflow.Random
Guid.NewGuid() Workflow.NewGuid()
Task.Delay Workflow.DelayAsync
Thread.Sleep Workflow.DelayAsync
Task.Run Workflow.RunTaskAsync
Task.WhenAll Workflow.WhenAllAsync
Task.WhenAny Workflow.WhenAnyAsync
System.Threading.Mutex Temporalio.Workflows.Mutex
System.Threading.Semaphore Temporalio.Workflows.Semaphore
CancellationTokenSource.CancelAsync CancellationTokenSource.Cancel

Testing Replay Compatibility

Use WorkflowReplayer to verify your code changes are compatible with existing histories. See the Workflow Replay Testing section of references/dotnet/testing.md.

Best Practices

  1. Always use Workflow.* APIs instead of standard .NET equivalents (see table above)
  2. Never use ConfigureAwait(false) in workflows
  3. Use SortedDictionary or sort before iterating collections
  4. Move all I/O operations (network, filesystem, database) into activities
  5. Use Workflow.Logger instead of Console.WriteLine for replay-safe logging
  6. Keep workflow code focused on orchestration; delegate non-deterministic work to activities
  7. Test with replay after making changes to workflow definitions