Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/cloud/get-started/api-keys.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ To use your API key with a Temporal SDK, see the instructions in each SDK sectio

[How to connect to Temporal Cloud using an API Key with the TypeScript SDK](/develop/typescript/client/temporal-client#connect-to-temporal-cloud)

[How to connect to Temporal Cloud using an API Key with the .NET SDK](/develop/dotnet/temporal-client#connect-to-temporal-cloud)
[How to connect to Temporal Cloud using an API Key with the .NET SDK](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud)

### tcld

Expand Down
2 changes: 1 addition & 1 deletion docs/cloud/get-started/certificates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ To view the current certificate filters, use the
- [PHP SDK](/develop/php/client/temporal-client#connect-to-a-dev-cluster)
- [Python SDK](/develop/python/client/temporal-client#connect-to-temporal-cloud)
- [TypeScript SDK](/develop/typescript/client/temporal-client#connect-to-temporal-cloud)
- [.NET SDK](/develop/dotnet/temporal-client#connect-to-temporal-cloud)
- [.NET SDK](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud)

### Configure Temporal CLI {#configure-temporal-cli}

Expand Down
4 changes: 2 additions & 2 deletions docs/cloud/get-started/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ See our guides for connecting each SDK to your Temporal Cloud Namespace:
- [Connect to Temporal Cloud in Java](/develop/java/client/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in Python](/develop/python/client/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in TypeScript](/develop/typescript/client/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in .NET](/develop/dotnet/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in .NET](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in PHP](/develop/php/client/temporal-client#connect-to-temporal-cloud)
- [Connect to Temporal Cloud in Ruby](/develop/ruby/client/temporal-client#connect-to-temporal-cloud)

Expand All @@ -68,7 +68,7 @@ See our guides for starting a workflow using each SDK:
- [Start a workflow in Java](/develop/java/client/temporal-client#start-workflow-execution)
- [Start a workflow in Python](/develop/python/client/temporal-client#start-workflow-execution)
- [Start a workflow in TypeScript](/develop/typescript/client/temporal-client#start-workflow-execution)
- [Start a workflow in .NET](/develop/dotnet/temporal-client#start-workflow)
- [Start a workflow in .NET](/develop/dotnet/client/temporal-client#start-workflow)
- [Start a workflow in PHP](/develop/php/client/temporal-client#start-workflow-execution)
- [Start a workflow in Ruby](/develop/ruby/client/temporal-client#start-workflow)

Expand Down
4 changes: 2 additions & 2 deletions docs/cloud/metrics/prometheus-grafana.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ If you're following through with the examples provided here, ensure that you hav
- [PHP](/develop/php/client/temporal-client#connect-to-a-dev-cluster)
- [Python](/develop/python/client/temporal-client#connect-to-temporal-cloud)
- [TypeScript](/develop/typescript/client/temporal-client#connect-to-temporal-cloud)
- [.NET](/develop/dotnet/temporal-client#connect-to-temporal-cloud)
- [.NET](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud)

- Grafana installed.

Expand Down Expand Up @@ -110,7 +110,7 @@ Each language development guide has details on how to set this up.
- [Java SDK](/develop/java/workers/observability#metrics)
- [TypeScript SDK](/develop/typescript/workers/observability#metrics)
- [Python](/develop/python/workers/observability#metrics)
- [.NET](/develop/dotnet/observability#metrics)
- [.NET](/develop/dotnet/workers/observability#metrics)

The following example uses the Java SDK to set the Prometheus registry and Micrometer stats reporter, set the scope, and
expose an endpoint from which Prometheus can scrape the SDK metrics.
Expand Down
4 changes: 2 additions & 2 deletions docs/cloud/metrics/sdk-metrics-setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Ensure Prometheus and Grafana are installed.
- [Java](/develop/java/client/temporal-client#connect-to-temporal-cloud)
- [Python](/develop/python/client/temporal-client#connect-to-temporal-cloud)
- [TypeScript](/develop/typescript/client/temporal-client#connect-to-temporal-cloud)
- [.NET](/develop/dotnet/temporal-client#connect-to-temporal-cloud)
- [.NET](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud)

## Expose a metrics endpoint {#sdk-metrics-setup}

Expand All @@ -52,7 +52,7 @@ Each language development guide has details on how to set this up.
- [Java SDK](/develop/java/workers/observability#metrics)
- [TypeScript SDK](/develop/typescript/workers/observability#metrics)
- [Python](/develop/python/workers/observability#metrics)
- [.NET](/develop/dotnet/observability#metrics)
- [.NET](/develop/dotnet/workers/observability#metrics)

For working examples of how to configure metrics in each SDK, see the metrics samples:

Expand Down
55 changes: 55 additions & 0 deletions docs/develop/dotnet/activities/basics.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
id: basics
title: Activity basics - .NET SDK
sidebar_label: Activity basics
description: This section explains Activity basics with the .NET SDK
toc_max_heading_level: 4
keywords:
- .NET SDK
tags:
- .NET SDK
- Temporal SDKs
---

## Develop an Activity {#develop-activity}

One of the primary things that Workflows do is orchestrate the execution of Activities.
An Activity is a normal method execution that's intended to execute a single, well-defined action (either short or long-running), such as querying a database, calling a third-party API, or transcoding a media file.
An Activity can interact with world outside the Temporal Platform or use a Temporal Client to interact with a Temporal Service.
For the Workflow to be able to execute the Activity, we must define the [Activity Definition](/activity-definition).

You can develop an Activity Definition by using the `[Activity]` attribute from the `Temporalio.Activities` namespace on the method.
To register a method as an Activity with a custom name, use an attribute parameter, for example `[Activity("your-activity")]`.
Otherwise, the activity name is the unqualified method name (sans an "Async" suffix if the method is async).

Activities can be asynchronous or synchronous.

```csharp
using Temporalio.Activities;

public class MyActivities
{
// Activities can be async and/or static too. We just demonstrate instance methods since many
// use them that way.
[Activity]
public string MyActivity(MyActivityParams input) =>
$"{input.Greeting}, {input.Name}!";
}
```

There is no explicit limit to the total number of parameters that an [Activity Definition](/activity-definition) may support.
However, there is a limit to the total size of the data that ends up encoded into a gRPC message Payload.

A single argument is limited to a maximum size of 2 MB.
And the total size of a gRPC message, which includes all the arguments, is limited to a maximum of 4 MB.

Also, keep in mind that all Payload data is recorded in the [Workflow Execution Event History](/workflow-execution/event#event-history) and large Event Histories can affect Worker performance.
This is because the entire Event History could be transferred to a Worker Process with a [Workflow Task](/tasks#workflow-task).

Some SDKs require that you pass context objects, others do not.
When it comes to your application data—that is, data that is serialized and encoded into a Payload—we recommend that you use a single object as an argument that wraps the application data passed to Activities.
This is so that you can change what data is passed to the Activity without breaking a method signature.

Activity parameters are the method parameters of the method with the `[Activity]` attribute.
These can be any data type Temporal can convert, including records.
Technically this can be multiple parameters, but Temporal strongly encourages a single parameter containing all input fields.
36 changes: 36 additions & 0 deletions docs/develop/dotnet/activities/dynamic-activity.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
id: dynamic-activity
title: Dynamic Activity - .NET SDK
sidebar_label: Dynamic Activity
description: This section explains Dynamic Activities with the .NET SDK
toc_max_heading_level: 4
keywords:
- .NET SDK
tags:
- .NET SDK
- Temporal SDKs
---

## Set a Dynamic Activity {#set-a-dynamic-activity}

**How to set a Dynamic Activity using the Temporal .NET SDK**

A Dynamic Activity in Temporal is an Activity that is invoked dynamically at runtime if no other Activity with the same name is registered.
An Activity can be made dynamic by setting `Dynamic` as `true` on the `[Activity]` attribute.
You must register the Activity with the Worker before it can be invoked.
Only one Dynamic Activity can be present on a Worker.

The Activity Definition must then accept a single argument of type `Temporalio.Converters.IRawValue[]`.
The [PayloadConverter](https://dotnet.temporal.io/api/Temporalio.Activities.ActivityExecutionContext.html#Temporalio_Activities_ActivityExecutionContext_PayloadConverter) property on the `ActivityExecutionContext` is used to convert an `IRawValue` object to the desired type using extension methods in the `Temporalio.Converters` namespace.

```csharp
public class MyActivities
{
[Activity(Dynamic = true)]
public string DynamicActivity(IRawValue[] args)
{
var input = ActivityExecutionContext.Current.PayloadConverter.ToValue<MyActivityParams>(args.Single());
return $"{input.Greeting}, {input.Name}!";
}
}
```
54 changes: 54 additions & 0 deletions docs/develop/dotnet/activities/execution.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
id: execution
title: Activity execution - .NET SDK
description: Shows how to perform Activity execution with the .NET SDK
sidebar_label: Activity execution
slug: /develop/dotnet/activities/execution
toc_max_heading_level: 3
tags:
- .NET SDK
- Temporal SDKs
- Activity
---

## Start Activity Execution {#activity-execution}

Calls to spawn [Activity Executions](/activity-execution) are written within a [Workflow Definition](/workflow-definition).
The call to spawn an Activity Execution generates the [ScheduleActivityTask](/references/commands#scheduleactivitytask) Command.
This results in the set of three [Activity Task](/tasks#activity-task) related Events ([ActivityTaskScheduled](/references/events#activitytaskscheduled), [ActivityTaskStarted](/references/events#activitytaskstarted), and ActivityTask[Closed]) in your Workflow Execution Event History.

A single instance of the Activities implementation is shared across multiple simultaneous Activity invocations.
Activity implementation code should be _idempotent_.

The values passed to Activities through invocation parameters or returned through a result value are recorded in the Execution history.
The entire Execution history is transferred from the Temporal service to Workflow Workers when a Workflow state needs to recover.
A large Execution history can thus adversely impact the performance of your Workflow.

Therefore, be mindful of the amount of data you transfer through Activity invocation parameters or Return Values.
Otherwise, no additional limitations exist on Activity implementations.

To spawn an Activity Execution, use the `ExecuteActivityAsync` operation from within your Workflow Definition.

```csharp
using Temporalio.Workflows;

[Workflow]
public class MyWorkflow
{
public async Task<string> RunAsync(string name)
{
var param = MyActivityParams("Hello", name);
return await Workflow.ExecuteActivityAsync(
(MyActivities a) => a.MyActivity(param),
new() { StartToCloseTimeout = TimeSpan.FromMinutes(5) });
}
}
```

Activity Execution semantics rely on several parameters.
The only required value that needs to be set is either a [Schedule-To-Close Timeout](/encyclopedia/detecting-activity-failures#schedule-to-close-timeout) or a [Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout).
These values are set in the Activity Options.

### Get Activity Execution results {#get-activity-results}
Comment thread
flippedcoder marked this conversation as resolved.

The Activity result is returned in the Task from the `ExecuteActivityAsync` call.
33 changes: 33 additions & 0 deletions docs/develop/dotnet/activities/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
id: index
title: Activities - .NET SDK
sidebar_label: Activities
description: This section explains how to implement Activities with the .NET SDK
toc_max_heading_level: 4
keywords:
- .NET SDK
tags:
- .NET SDK
- Temporal SDKs
---

import * as Components from '@site/src/components';

![.NET SDK Banner](/img/assets/banner-dotnet-temporal.png)

## Activities

- [Activity basics](/develop/dotnet/activities/basics)
- [Activity execution](/develop/dotnet/activities/execution)
- [Timeouts](/develop/dotnet/activities/timeouts)
- [Asynchronous Activity completion](/develop/dotnet/activities/asynchronous-activity)
- [Dynamic Activity](/develop/dotnet/activities/dynamic-activity)
- [Benign exceptions](/develop/dotnet/activities/benign-exceptions)

### [Standalone Activities](/develop/dotnet/activities/standalone-activities)

Execute Activities independently without a Workflow using the Temporal Client.

- [How to execute a Standalone Activity](/develop/dotnet/activities/standalone-activities#execute-activity)
- [How to start a Standalone Activity without waiting](/develop/dotnet/activities/standalone-activities#start-activity)
- [How to get a handle to an existing Standalone Activity](/develop/dotnet/activities/standalone-activities#get-activity-handle)
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Workflow. Instead of starting an Activity from within a Workflow Definition, you
Activity directly from a Temporal Client.

The way you write the Activity and register it with a Worker is identical to [Workflow
Activities](/develop/dotnet/core-application#develop-activity). The only difference is that you execute a
Activities](/develop/dotnet/activities/basics#develop-activity). The only difference is that you execute a
Standalone Activity directly from your Temporal Client.

This page covers the following:
Expand Down Expand Up @@ -135,7 +135,7 @@ public record ComposeGreetingInput(string Greeting, string Name);
Running a Worker for Standalone Activities is the same as running a Worker for Workflow Activities —
you create a Worker, register the Activity, and run the Worker. The Worker doesn't need to know
whether the Activity will be invoked from a Workflow or as a Standalone Activity. See [How to develop
a Worker](/develop/dotnet/core-application#run-worker-process) for more details on Worker setup and
a Worker](/develop/dotnet/workers/run-worker-process) for more details on Worker setup and
configuration options.

[src/StandaloneActivity/Program.cs](https://github.com/temporalio/samples-dotnet/blob/main/src/StandaloneActivity/Program.cs)
Expand Down Expand Up @@ -401,7 +401,7 @@ profile. No code changes are needed.

For full details on connecting to Temporal Cloud, including Namespace creation, certificate
generation, and authentication options, see
[Connect to Temporal Cloud](/develop/dotnet/temporal-client#connect-to-temporal-cloud).
[Connect to Temporal Cloud](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud).

### Connect with mTLS

Expand Down
Loading
Loading