diff --git a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs
index 4f6b68a1d..b66b0090d 100644
--- a/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs
+++ b/src/clients/Elsa.Api.Client/Resources/ActivityDescriptors/Models/ActivityDescriptor.cs
@@ -10,17 +10,17 @@ public record ActivityDescriptor
///
/// The fully qualified name of the activity type.
///
- public string TypeName { get; init; } = default!;
+ public string TypeName { get; init; } = null!;
///
/// The namespace of the activity type.
///
- public string Namespace { get; init; } = default!;
+ public string Namespace { get; init; } = null!;
///
/// The name of the activity type.
///
- public string Name { get; init; } = default!;
+ public string Name { get; init; } = null!;
///
/// The version of the activity type.
@@ -30,7 +30,7 @@ public record ActivityDescriptor
///
/// The category of the activity type.
///
- public string Category { get; init; } = default!;
+ public string Category { get; init; } = null!;
///
/// The display name of the activity type.
diff --git a/src/modules/Elsa.Workflows.Core/Attributes/ActivityAttribute.cs b/src/modules/Elsa.Workflows.Core/Attributes/ActivityAttribute.cs
index 068ad408b..d01b59cc9 100644
--- a/src/modules/Elsa.Workflows.Core/Attributes/ActivityAttribute.cs
+++ b/src/modules/Elsa.Workflows.Core/Attributes/ActivityAttribute.cs
@@ -8,21 +8,21 @@ public class ActivityAttribute : Attribute
// Default constructor.
}
- public ActivityAttribute(string @namespace, string? category, string? description = default)
+ public ActivityAttribute(string @namespace, string? category, string? description = null)
{
Namespace = @namespace;
Description = description;
Category = category;
}
- public ActivityAttribute(string @namespace, string? description = default)
+ public ActivityAttribute(string @namespace, string? description = null)
{
Namespace = @namespace;
Description = description;
Category = @namespace;
}
- public ActivityAttribute(string @namespace, string? type, int version = 1, string? description = default, string? category = default)
+ public ActivityAttribute(string @namespace, string? type, int version = 1, string? description = null, string? category = null)
{
Namespace = @namespace;
Type = type;
@@ -38,4 +38,5 @@ public class ActivityAttribute : Attribute
public string? DisplayName { get; set; }
public string? Category { get; set; }
public ActivityKind Kind { get; set; } = ActivityKind.Action;
+ public bool RunAsynchronously { get; set; }
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Attributes/TaskActivityAttribute.cs b/src/modules/Elsa.Workflows.Core/Attributes/TaskActivityAttribute.cs
deleted file mode 100644
index 390cfd628..000000000
--- a/src/modules/Elsa.Workflows.Core/Attributes/TaskActivityAttribute.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Elsa.Workflows.Attributes;
-
-[AttributeUsage(AttributeTargets.Class)]
-public class TaskActivityAttribute : ActivityAttribute
-{
- public TaskActivityAttribute()
- {
- Kind = ActivityKind.Task;
- }
-
- public TaskActivityAttribute(string @namespace, string? category, string? description = null, bool runAsynchronously = false)
- : base(@namespace, category, description)
- {
- Kind = ActivityKind.Task;
- RunAsynchronously = runAsynchronously;
- }
-
- public bool RunAsynchronously { get; set; }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Models/ActivityConstructorContext.cs b/src/modules/Elsa.Workflows.Core/Models/ActivityConstructorContext.cs
index 2e36b9859..38f35415b 100644
--- a/src/modules/Elsa.Workflows.Core/Models/ActivityConstructorContext.cs
+++ b/src/modules/Elsa.Workflows.Core/Models/ActivityConstructorContext.cs
@@ -49,24 +49,13 @@ public static class JsonActivityConstructorContextHelper
// 7) Pull out your boolean flags from the cleaned element
var canStartWorkflow = GetBoolean(cleanedElement, "canStartWorkflow");
- var runAsynchronously = GetNullableBoolean(cleanedElement, "runAsynchronously");
- if (runAsynchronously is null)
- {
- if (activityDescriptor.Attributes.OfType().FirstOrDefault() is { } taskActivityAttribute)
- {
- runAsynchronously = taskActivityAttribute.RunAsynchronously;
- }
- else
- {
- runAsynchronously = false;
- }
- }
+ var runAsynchronously = GetNullableBoolean(cleanedElement, "runAsynchronously") ?? activityDescriptor.RunAsynchronously;
// 8) If composite, setup
if (activity is IComposite composite)
composite.Setup();
- // 9) Your existing synthetic inputs/outputs routines, using the cleanedElement
+ // 9) Existing synthetic inputs/outputs routines, using the cleanedElement
ReadSyntheticInputs(activityDescriptor, activity, cleanedElement, serializerOptions);
ReadSyntheticOutputs(activityDescriptor, activity, cleanedElement);
diff --git a/src/modules/Elsa.Workflows.Core/Models/ActivityDescriptor.cs b/src/modules/Elsa.Workflows.Core/Models/ActivityDescriptor.cs
index 89f214934..8b6cf8675 100644
--- a/src/modules/Elsa.Workflows.Core/Models/ActivityDescriptor.cs
+++ b/src/modules/Elsa.Workflows.Core/Models/ActivityDescriptor.cs
@@ -76,6 +76,11 @@ public class ActivityDescriptor
///
public ActivityKind Kind { get; set; } = ActivityKind.Action;
+ ///
+ /// Whether the activity should be executed asynchronously. Applies only when the Kind is set to Task and as a default when not set on the activity itself.
+ ///
+ public bool RunAsynchronously { get; set; }
+
///
/// The ports of the activity type.
///
diff --git a/src/modules/Elsa.Workflows.Runtime/Middleware/Activities/BackgroundActivityInvokerMiddleware.cs b/src/modules/Elsa.Workflows.Runtime/Middleware/Activities/BackgroundActivityInvokerMiddleware.cs
index 30277beb9..05242c9eb 100644
--- a/src/modules/Elsa.Workflows.Runtime/Middleware/Activities/BackgroundActivityInvokerMiddleware.cs
+++ b/src/modules/Elsa.Workflows.Runtime/Middleware/Activities/BackgroundActivityInvokerMiddleware.cs
@@ -117,15 +117,7 @@ public class BackgroundActivityInvokerMiddleware(
return false;
var runAsynchronously = activity.GetRunAsynchronously();
-
- if (runAsynchronously is null)
- {
- var taskActivityAttribute = activityDescriptor.Attributes.OfType().FirstOrDefault();
-
- return taskActivityAttribute is { RunAsynchronously: true };
- }
-
- return (bool)runAsynchronously;
+ return runAsynchronously ?? activityDescriptor.RunAsynchronously;
}
private static bool GetIsBackgroundExecution(ActivityExecutionContext context) => context.TransientProperties.ContainsKey(BackgroundActivityExecutionContextExtensions.IsBackgroundExecution);