Skip to content

Instantly share code, notes, and snippets.

@noseratio
Created December 2, 2021 10:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noseratio/caa5cef306aed528ca9ea889b427a6ef to your computer and use it in GitHub Desktop.
Save noseratio/caa5cef306aed528ca9ea889b427a6ef to your computer and use it in GitHub Desktop.
async void event handlers and reentrancy
// https://twitter.com/noseratio/status/1466350790952456192?s=20
// dotnet new winforms -n app
// paste this into Form1.cs
namespace app;
public partial class Form1 : Form
{
int _count = 0;
Button _button;
readonly SemaphoreSlim _semaphoreSlim = new(initialCount: 1, maxCount: 1);
CancellationTokenSource? _cancellationSource;
public Form1()
{
InitializeComponent();
_button = new Button() { Text = "Click me", AutoSize = true };
_button.Click += Button_Click;
this.Controls.Add(_button);
}
private async void Button_Click(object? sender, EventArgs e)
{
try
{
// cancel the previous click handler workflow
_cancellationSource?.Cancel();
_cancellationSource = new();
await _semaphoreSlim.WaitAsync(_cancellationSource.Token);
try
{
// simualte async operation
await Task.Delay(1000, _cancellationSource.Token);
// update the UI (a ViewModel in real life)
_button.Text = $"Clicked {++_count} times";
}
finally
{
_semaphoreSlim.Release();
}
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment