Search code examples
c#.netasynchronouseventscancellationtokensource

Waiting for single event with timeout


My current solution requires a class global CancellationTokenSource. It is possible to do the same without it?

CancellationTokenSource _waitCTS = null;

private async Task WaitWithTimeout(string param)
{
    _waitCTS?.Dispose();
    _waitCTS = new CancellationTokenSource();

    XClass x = new XClass(param);
    x.OnReceived += X_OnReceived;

    try
    {
        await Task.Delay(5000, _waitCTS.Token).ConfigureAwait(true);
    }
    catch (TaskCanceledException)
    {
        Debug.WriteLine("Timed out");
    }

    x.OnReceived -= X_OnReceived;
    x.Cleanup();
}

private void X_OnReceived(object sender, SelectedItemEventArgs e)
{
    Debug.WriteLine(e.ReceivedItem);
    if (_waitCTS != null)
        _waitCTS.Cancel();
}

Solution

  • You can make the handler a local that captures the CancellationTokenSource variable. EG something like:

    private async Task WaitWithTimeout(string param)
    {
        var CancellationTokenSource _waitCTS = new CancellationTokenSource();
    
        XClass x = new XClass(param);
        SelectedItemEventHandler X_OnReceived = (s, e) =>
        {
            Debug.WriteLine(e.ReceivedItem);
            _waitCTS.Cancel();
        }
    
        x.OnReceived += X_OnReceived;
    
    
        try
        {
            await Task.Delay(5000, _waitCTS.Token).ConfigureAwait(true);
        }
        catch (TaskCanceledException)
        {
            Debug.WriteLine("Timed out");
        }
    
        x.OnReceived -= X_OnReceived;
        x.Cleanup();
    }