2

I'm trying to disable frequent user gestures so the same command does not get executed multiple times simultaneously.

private readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1);             
public bool MyCommandCanExecute { get; set; } = true;
public DelegateCommand MyCommand { get; set; }

MyCommand = new DelegateCommand(async () =>
{
  await _semaphoreSlim.WaitAsync();

  try
  {
       MyCommandCanExecute = false;
       // run code
  }
  finally
  {
       MyCommandCanExecute = true;
       _semaphoreSlim.Release();
  }
}).ObservesCanExecute(p => MyCommandCanExecute);

I'm not sure if I'm doing this right.

  • Is SemaphoreSlim overkill or should I leave it there to be safe?
  • Is ObservesCanExecute() needed since I'm manually turning the flag on and off?
  • I have several commands in the same view model, each with a separate CanExecute flag. I'm thinking I will soon run into cases where one command needs to be enabled while another is running. Does _semaphoreSlim hold off all commands while one is in progress or does it hold off multiple invocations of the same command?
Mark13426
  • 2,569
  • 6
  • 41
  • 75

1 Answers1

1
  • ObservesCanExecute works with properties that trigger PropertyChanged (it won't poll a regular property for changes)

  • Your _semaphoreSlim let's one thread pass, no matter what command the thread is executing. So, if you want CommandA and CommandB to execute in parallel, but only one of each of them at a time, you'll need _semaphoreSlimA and _semaphoreSlimB

  • As for SemaphoreSlim - if you want only one thread to pass, a AsyncAutoResetEvent would do the same thing but more understandable.

  • If you do not want commands of a type to queue up, use AutoResetEvent and try to WaitOne(0), aborting the command if you don't aquire the lock.

Haukinger
  • 10,420
  • 2
  • 15
  • 28