Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 6875865

Browse files
Add SemaphoreSlim
1 parent 28db359 commit 6875865

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

src/CommunityToolkit/Xamarin.CommunityToolkit/ObjectModel/Internals/BaseCommand.shared.cs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.ComponentModel;
3+
using System.Threading;
4+
using System.Threading.Tasks;
35
using Xamarin.CommunityToolkit.Helpers;
46
using Xamarin.Forms;
57

@@ -12,9 +14,10 @@ namespace Xamarin.CommunityToolkit.ObjectModel.Internals
1214
public abstract partial class BaseCommand<TCanExecute>
1315
{
1416
readonly Func<TCanExecute?, bool> canExecute;
17+
readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1);
1518
readonly DelegateWeakEventManager weakEventManager = new DelegateWeakEventManager();
1619

17-
volatile int executionCount;
20+
int executionCount;
1821

1922
/// <summary>
2023
/// Initializes BaseCommand
@@ -51,18 +54,11 @@ protected int ExecutionCount
5154
get => executionCount;
5255
set
5356
{
54-
var shouldRaiseCanExecuteChanged = (AllowsMultipleExecutions, executionCount, value) switch
55-
{
56-
(true, _, _) => false,
57-
(false, 0, >0) => true,
58-
(false, >0, 0) => true,
59-
(false, _, _) => false
60-
};
57+
var previousExecutionCount = executionCount;
6158

6259
executionCount = value;
6360

64-
if (shouldRaiseCanExecuteChanged)
65-
RaiseCanExecuteChanged();
61+
HandleExecutionCountChanged(previousExecutionCount, value).SafeFireAndForget();
6662
}
6763
}
6864

@@ -95,5 +91,28 @@ public void RaiseCanExecuteChanged()
9591
/// </summary>
9692
[EditorBrowsable(EditorBrowsableState.Never)]
9793
public void ChangeCanExecute() => RaiseCanExecuteChanged();
94+
95+
async Task HandleExecutionCountChanged(int updatedExecutionCount, int previousExecutionCount)
96+
{
97+
await semaphoreSlim.WaitAsync().ConfigureAwait(true);
98+
99+
try
100+
{
101+
var shouldRaiseCanExecuteChanged = (AllowsMultipleExecutions, updatedExecutionCount, previousExecutionCount) switch
102+
{
103+
(true, _, _) => false,
104+
(false, 0, > 0) => true,
105+
(false, > 0, 0) => true,
106+
(false, _, _) => false
107+
};
108+
109+
if (shouldRaiseCanExecuteChanged)
110+
RaiseCanExecuteChanged();
111+
}
112+
finally
113+
{
114+
semaphoreSlim.Release();
115+
}
116+
}
98117
}
99118
}

0 commit comments

Comments
 (0)