This works:
int _counter;
readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
async void Button_Click(object sender, RoutedEventArgs e)
{
if (_semaphore.Wait(0))
{
Title = $"{ ++_counter}";
await Task.Delay(1000); // simulate work
Title = $"{ --_counter}";
_semaphore.Release();
}
}
After first click further buttons clicks are ignored until work is finished. Tittle
can be 1
or 0
.
And this doesn't work
void Button_Click(object sender, RoutedEventArgs e)
{
if (_semaphore.Wait(0))
{
Test(); // moving code into separate method
_semaphore.Release();
}
}
async void Test()
{
Title = $"{ ++_counter}";
await Task.Delay(1000); // simulate work
Title = $"{ --_counter}";
}
Clicking button continuously will rise Tittle
to 2
, 3
, and so on.
What am I doing wrong?
async void
only makes sense in event handlers. It is a special type of asynchronism. It means "fire and forget".You don't want to fire and forget the
Test()
method. You want to wait for it to return.Change your
Test
signature to:And then await it on your event handler: