Skip to content

Task automation recipes

These helpers use the supported Tasks C# services inside a Net Operation Project. They are ordinary classes, not discoverable function entry points. Call them from an admitted function using its injected services and current actor. Use the installed developer-surface and XML reference to check member availability before adding them to your project.

Author and invoke your function through the documented workspace API, resolving routes against WORKSPACE_API_BASE_URL, never moltaro.com. Direct Tasks HTTP operations are documented in the installation’s Runtime and Configuration OpenAPI documents. See runtime automation for authority, phases and separate-transaction behavior.

The caller creates and persists one OperationId before submission. Keep it when the response is lost. A deliberate later request uses a new key. The service resolves the current user’s Worker; neither the helper nor its arguments choose another recipient. Use a user-authorized Action, Command or HttpEndpoint for self-service acquisition. A system Job is not a replacement for that user.

using System.Threading;
using System.Threading.Tasks;
using Moltaro.Package.NET.Tasks.Automation;
using Moltaro.Package.NET.Tasks.Queues;
public sealed class TaskWorkRequestClient(
ITaskQueueAssignmentAutomationCommandService commands,
ITaskQueueAssignmentAutomationQueryService queries)
{
public async Task<TaskQueueAssignmentOperation> SubmitAsync(
string queueId, string operationId, CancellationToken token)
{
var result = await commands.RequestWorkAsync(
queueId, new TaskQueueAssignmentRequest(operationId), token);
result.ThrowIfFailed();
return result.Data!;
}
public async Task<TaskQueueAssignmentOperation> ReadAsync(
string queueId, string operationId, CancellationToken token)
{
var result = await queries.GetWorkRequestAsync(queueId, operationId, token);
result.ThrowIfFailed();
return result.Data!;
}
public static bool IsPending(TaskQueueAssignmentOperation request) =>
request.Status is TaskQueueAssignmentStatusEnum.Pending
or TaskQueueAssignmentStatusEnum.Running;
}

Return the receipt to the caller. While pending, read it with a bounded polling interval and stop waiting on cancellation or the caller’s deadline. Cancellation stops that wait; it does not cancel the admitted assignment.

Handle terminal states explicitly: Succeeded is a committed result, NoWork is a normal terminal outcome, and Failed needs its safe ReasonCode inspected. Succeeded with Task = null is currently unavailable to this reader; do not automatically submit another request. Historical ExistingWork values may be replayed, but a new request attempts a new assignment in the current contract.

For dispatcher distribution, use EvaluateAssignmentAsync and read GetAssignmentDiagnosticAsync(queueId, receipt.Id). The opaque receipt Id is different from a Work request’s client OperationId. Follow CanRetry and current authority for RetryAssignmentAsync; an explicit retry has a distinct key.

Use the instance examples for create, data edits, lifecycle and Queue commands. Read current command/edit/routing options before forming a new intent; snapshots are not durable authorization.

MoltaroRuntimeResult.Errors contains stable Code, Type and optional Field. When the function must fail, ThrowIfFailed() preserves the platform reason in the function result. For a recoverable form, return safe structured errors to its caller instead of replacing them with a generic exception.

Result or failureNext step
ValidationCorrect the named input or unmet requirement; create a new intent for changed input.
Conflict/stale versionReread current state and reconcile; an exact transport replay keeps its original payload and key.
Forbidden / NotFoundRespect current authority and redaction. Do not switch to system execution or direct EF to bypass it.
tasks.runtime.retryRequiredThe native transaction retry budget was exhausted and the operation rolled back; apply bounded retry policy. Do not infer rollback from an unrelated network timeout.
Queued Pending/RunningRead the existing receipt; do not create another command just to check progress.

Keep operation keys in the calling application’s durable workflow, scoped to the actor and intention. A new random key generated on every retry defeats deduplication even when the business payload looks identical.