Thetype exposes the following members.
Returns the URI the client is listening on for requests from the temporal-proxy.
Returns the URI the associated temporal-proxy instance is listening on.
Returns the settings used to create the client.
Controls how synchronous signals operations are polled until the signal operation is completed. This defaults to something reasonable.
Used to externally complete an activity identified by WorkflowExecution and activity ID.
Used to externally complete an activity identified by task token.
Used to externally fail an activity by WorkflowExecution and activity ID.
Used to externally fail an activity by task token.
Used to record an activity heartbeat externally by WorkflowExecution and activity ID.
Used to record an activity heartbeat externally by task token.
Prebuilds and caches the internal activity stub class backing the TActivity interface. Subsequent calls for the same activity interface can be made but actually do nothing.
Scans the assembly passed for any workflow or activity interfaces and pebuilds and caches the generated internal backing classes. Subsequent calls for the same assembly can be made but actually do nothing.
Prebuilds and caches the internal workflow stub class backing the TWorkflow interface. Subsequent calls for the same workflow interface can be made but actually do nothing.
Establishes a connection to a Temporal cluster.
INTERNAL USE ONLY: Appends a line of text to the debug log which is used internally to debug generated code like stubs. This hardcodes its output to C:\Temp\temporal-debug.log so this currently only works on Windows.
Describes the named Temporal namespace.
Returns information about pollers (AKA workers) that have communicated with the Temporal cluster in the last few minutes.
Returns the current state of a running workflow.
|DescribeWorkflowExecutionAsync(String, String, String)|
Describes a workflow execution by explicit IDs.
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
Releases all associated resources.
Determines whether the specified object is equal to the current object.(Inherited from Object.)
Writes the temporal-proxy binaries to the specified folder. This is provided so that you can pre-provision the executable and then use the BinaryPath setting to reference it. These files will be written:
This is useful for situations where the executable must be pre-provisioned for security. One example is deploying Temporal workers to a Docker container with a read-only file system.
Serves as the default hash function.(Inherited from Object.)
Gets the Type of the current instance.(Inherited from Object.)
Returns the current maximum number of sticky workflows for which history will be retained as a performance optimization.
Lists the Temporal namespaces.
Creates a shallow copy of the current Object.(Inherited from Object.)
Creates an untyped stub that can be used to start a single workflow execution.
Creates an untyped stub for a known workflow execution.
|NewUntypedWorkflowStub(String, String, String)|
Creates an untyped stub for a known workflow execution.
Creates a new Temporal Worker attached to the current client. You'll use this to register your workflow and/or activity implementations with Temporal and the start the worker to signal Temporal that the worker is ready for business.
Creates a stub suitable for starting an external workflow and then waiting for the result as separate operations.
Creates an untyped workflow stub to be used for launching a workflow.
Creates a typed workflow stub that can be used to start as well as query and signal the workflow via the type-safe interface methods.
Creates a typed workflow stub connected to a known workflow execution using a WorkflowExecution. This can be used to signal and query the workflow via the type-safe interface methods.
|NewWorkflowStubTWorkflowInterface(String, String, String)|
Creates a typed workflow stub connected to a known workflow execution using IDs. This can be used to signal and query the workflow via the type-safe interface methods.
Pings the temporal-proxy and waits for the reply. This is used mainly for low-level performance and load testing but can also be used to explicitly verify that the temporal-proxy is still alive.
Registers a Temporal namespace using the specified parameters.
Sets the maximum number of sticky workflows for which of history will be retained for workflow workers created by this client as a performance optimization. When this is exceeded, Temporal will may need to retrieve the entire workflow history from the Temporal cluster when a workflow is scheduled on the client's workers.
This defaults to 10K sticky workflows.
Terminates a workflow if it has not already finished.
Returns a string that represents the current object.(Inherited from Object.)
Updates the named Temporal namespace.
Waits for a resonable period of time for Temporal to start a workflow.
Raised when the connection is closed. You can determine whether the connection was closed normally or due to an error by examining the TemporalClientClosedArgs arguments passed to the handler.
To get started with Temporal, you'll need to deploy a Temporal cluster with one or more nodes and the establish a connection to the cluster from your workflow/activity implementations and management tools. This is pretty easy to do.
Temporal clusters interacts with client APIs via gRPC on port 7233 (by default). Server nodes are typically configured behind a TCP load balancer or a DNS name is configured such that it returns the IP addresses for each server node. The HostPort property is used to specify how to connect to the cluster. For single node clusters or clusters behind a load balancer, you'll typically specify HOST:7233 where HOST is the DNS name or IP address for the node.
Alternatively, if you've configured DNS to return IP addresses for each cluster node, you can specify dns:///host:port. In this case, the client will round-robin between the node addresses returned to locate healthy nodes to communicate with.
To establish a connection, you'll construct a TemporalSettings and add your cluster endpoint to the HostPort and then call the static ConnectAsync(TemporalSettings) method to obtain a connected . You'll use this for registering workflows and activities types as well as the workers that indicate that workflows and activities can be executed in the current process.
|IMPORTANT: The current .NET Temporal client release supports having only one client open at a time. A NotSupportedException will be thrown when attempting to connect a second client. This restriction may be relaxed for future releases.|
You'll implement your workflows and activities by implementing classes that derive from WorkflowBase and ActivityBase and then registering these types with Temporal. Then you'll start workflow or activity workers so that Temporal will begin scheduling operations for execution by your code. Workflows and activities are registered using the fully qualified names of the derived WorkflowBase and ActivityBase types by defaut, but you can customize this if desired.
Temporal supports the concept of namespaces and task lists. Temporal is multi-tenant and namespaces are simply string names used to isolate deployments. For example, you could define a PROD namespace for your production workflows and STAGE for preproduction. It's also often useful to organize namespaces by the teams implementing and managing their workflows. Each Namespace and this defaults to "default" unless you specify something different when connecting the client.is assigned to a default namespace via
|You can override the default client namespace for specific operations via WorkerOptions, StartWorkflowOptions, ChildWorkflowOptions, ActivityOptions as well as via the WorkflowInterfaceAttribute, WorkflowMethodAttribute, ActivityInterfaceAttribute and ActivityMethodAttribute attributes decorating your workflow and activity interface definitions.|
Workflows and activities are implemented by creating a Worker via NewWorkerAsync(String, String, WorkerOptions), registering your workflow and activity implementations with the worker and then starting the worker via StartAsync. Temporal will begin scheduling pending workflows and activities on workers after they've been started.
The Worker class provides methods for registering individual workflow and activity implementations, including RegisterWorkflowAsyncTWorkflow(Boolean) and RegisterActivityAsyncTActivity(Boolean) as well as methods that register all workflow and activity implementation discovered in an assembly: RegisterAssemblyActivitiesAsync(Assembly, Boolean), RegisterAssemblyWorkflowsAsync(Assembly, Boolean), and RegisterAssemblyAsync(Assembly, Boolean) (which registers both workflow and assembly implementations).
Workflows are implemented by defining an interface describing the workflow methods and then writing a class the implements your interface and also inherits WorkflowBase. Your workflow interface must define at least one entry point method tagged by WorkflowMethodAttribute and may optionally include signal and query methods tagged by SignalMethodAttribute and QueryMethodAttribute.
Activities are implemented in the same way by defining an activity interface and then writing a class that implements this interface. and inherits ActivityBase. Your activity interface must define at least one entry point method.
You'll generally create stub classes to start and manage workflows and activities. These come in various flavors with the most important being typed and untyped stubs. Typed stubs are nice because they implement your workflow or activity interface so that the C# compiler can provide compile-time type checking. Untyped stubs provide a way to interact with workflows and activities written on other languages or for which you don't have source code.
You can create typed external workflow stubs via NewWorkflowStubTWorkflowInterface(String, String, String) and NewWorkflowStubTWorkflowInterface(StartWorkflowOptions, String).
Workflows can use their Workflow property to create child workflow as well as activity stubs.
Task lists are used by Temporal to identify the set of workflows and activities that are implemented by workers. For example, if you deploy a program called payments.exe that implements payment related workflows and activities like validate, debit, credit,... you could register these and then start a worker using taskqueue=payments.
You'll need to provide the correct task queue when executing a workflow or normal (non-local) activity. Temporal will schedule the workflow or activity on one of the workers that was started with the specified task queue. The most convienent way to specify the task queue is to tag your workflow and activity interfaces with [WorkflowInterface(TaskQueue = "payments")] and [ActivityInterface(TaskQueue = "payments")] attributes, specifying the target task queue.
|You may specify a default task queue when connecting a TaskQueue (which defaults to null). This may be convienent for simple deployments.via|
You may also specify a custom task queue in the workflow and activity options used when executing a workflow or activity. A task queue specified in one of these options takes precedence over the task queue specified in an attribute.
|The .NET client will complain if a task queue is not specified in either an interface attribute via options and the there's no client default task queue set.|
IMPORTANT: You need to take care to ensure that the task lists you use for your workers uniquely identify the set of workflows and activities implemented by your the workers. For example, if you start two workers, worker-a and worker-b using the same task queue, but worker-a registers the foo workflow and worker-b registers the bar activity, you're going run into trouble.
The problem is that Cadence assumes that both workers implement the same workflows, both foo and bar in this case. Say you start a foo workflow. Temporal will select one of worker-a or worker-b to run the workflow. If Temporal happens to select worker-a everything will work as expected because foo is registered there. If Temporal selects worker-b the initial execution will fail because foo is not registered there. Temporal handles this a decision task failure and will attempt to reschedule the workflow on another worker (hopefully worker-a this time).
Temporal fault tolerance will probably end up being able to handle this sort misconfiguration, but at the cost of additional delays as well as unnecessary communication overhead to workers that will never be able to execute unregistered workflows and activities.
So the moral of this store is carefully choose your task lists to match the set of workflows and activities implemented by your application. One common approach is to name the task queue after the service or application that implements the workflow anbd activities.
Activity and workflow stubs are generated and compiled on demand by default. This takes about 500ms for each stub. This generally works fine but may cause decision task timeouts for workflows that call a lot of different child workflows or activities.
The default workflow decision task timeout is 10 seconds, so a workflow that creates 22 stubs when its first called will have a decent chance of timing out due to the 500ms * 22 = 11 seconds it will take for the .NET client generate and build the backing classes.
You can proactively address this by prebuilding stub classes before starting any workers by calling BuildActivityStubTActivity, BuildWorkflowStubTWorkflow, and/or BuildAssemblyStubs(Assembly). After doing this, the specified stubs will already be generated and compiled when the worker starts and begins invoking workflows and activities.