Skip to content

Commit 6d73083

Browse files
committed
Add AsyncRelayCommandOptions enum
1 parent 69419e7 commit 6d73083

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
7+
namespace CommunityToolkit.Mvvm.Input;
8+
9+
/// <summary>
10+
/// Options to customize the behavior of <see cref="AsyncRelayCommand"/> and <see cref="AsyncRelayCommand{T}"/> instances.
11+
/// </summary>
12+
[Flags]
13+
public enum AsyncRelayCommandOptions
14+
{
15+
/// <summary>
16+
/// No option is specified. The <see cref="AsyncRelayCommand"/> and <see cref="AsyncRelayCommand{T}"/> types will use their default behavior:
17+
/// <list type="bullet">
18+
/// <item>Concurrent execution is disallowed: a command is disabled if there is a pending asynchronous execution running.</item>
19+
/// <item>
20+
/// <para>
21+
/// Exceptions are thrown on the calling context: calling <see cref="AsyncRelayCommand.Execute(object?)"/> will await the
22+
/// returned <see cref="System.Threading.Tasks.Task"/> for the operation, and propagate the exception on the calling context.
23+
/// </para>
24+
/// <para>This behavior is consistent with synchronous commands, where exceptions in <see cref="RelayCommand.Execute(object?)"/> behave the same.</para>
25+
/// </item>
26+
/// </list>
27+
/// </summary>
28+
None = 0,
29+
30+
/// <summary>
31+
/// <para>Concurrent executions are allowed. This option makes it so that the same command can be invoked concurrently multiple times.</para>
32+
/// <para>
33+
/// Note that additional considerations should be taken into account in this case:
34+
/// <list type="bullet">
35+
/// <item>If the command supports cancellation, previous invocations will automatically be canceled if a new one is started.</item>
36+
/// <item>The <see cref="AsyncRelayCommand.ExecutionTask"/> property will always represent the operation that was started last.</item>
37+
/// </list>
38+
/// </para>
39+
/// </summary>
40+
AllowConcurrentExecutions = 1 << 0,
41+
42+
/// <summary>
43+
/// <para>Exceptions are not thrown on the calling context, and are propagated to <see cref="System.Threading.Tasks.TaskScheduler.UnobservedTaskException"/> instead.</para>
44+
/// <para>
45+
/// This affects how calls to <see cref="AsyncRelayCommand.Execute(object?)"/> behave. When this option is used, if an operation fails, that exception will not
46+
/// be rethrown on the calling context (as it is not awaited there). Instead, it will flow to <see cref="System.Threading.Tasks.TaskScheduler.UnobservedTaskException"/>.
47+
/// </para>
48+
/// <para>
49+
/// This option enables more advanced scenarios, where the <see cref="AsyncRelayCommand.ExecutionTask"/> property can be used to inspect the state of an operation
50+
/// that was queued. That is, even if the operation failed or was canceled, the details of that can be retrieved at a later time by accessing this property.
51+
/// </para>
52+
/// </summary>
53+
FlowExceptionsToTaskScheduler = 1 << 1
54+
}

CommunityToolkit.Mvvm/Input/Attributes/RelayCommandAttribute.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ public sealed class RelayCommandAttribute : Attribute
7878
/// When set for an attribute used on a method that would result in an <see cref="AsyncRelayCommand"/> or an
7979
/// <see cref="AsyncRelayCommand{T}"/> property to be generated, this will modify the behavior of these commands
8080
/// when an execution is invoked while a previous one is still running. It is the same as creating an instance of
81-
/// these command types with a constructor such as <see cref="AsyncRelayCommand(Func{System.Threading.Tasks.Task}, bool)"/>.
81+
/// these command types with a constructor such as <see cref="AsyncRelayCommand(Func{System.Threading.Tasks.Task}, AsyncRelayCommandOptions)"/>
82+
/// and using the <see cref="AsyncRelayCommandOptions.AllowConcurrentExecutions"/> value.
8283
/// </summary>
8384
/// <remarks>Using this property is not valid if the target command doesn't map to an asynchronous command.</remarks>
8485
public bool AllowConcurrentExecutions { get; init; }

0 commit comments

Comments
 (0)