0

In the event handler for the "connect" event, I need to start a task that may take a long time to complete, and I need to wait for its result. While the task is running, the "connect" event may be raised again, which should interrupt the previous operation and start a new one.

The problem is that the "connect" event can be raised from different threads. So cancellation of the previous task should be thread safe. How can I achieve a thread-safe cancellation of the previous task?

I found these two answers but none of them contains a thread-safe solution:

I came up with a following solution (which is not thread-safe):

CancellationTokenSource cts;
        
async void OnConnected() 
{
    cts?.Cancel();
    var currentCts = cts = new CancellationTokenSource();   

    try
    {
        var result = await LongRunningTask(currentCts.Token);
        //Do something with result if LongRinningTask was not cancelled
    }
    finally
    {
        currentCts.Dispose();               
    }
}
    
await Task<bool> LongRunningTask(CancellationToken ct)
{
    try
    {
        await Task.Delay(TimeSpan.FromHours(1), ct);
        return true;
    }       
    catch(Exception)
    {
        return false;
    }
}

Is it sufficient to achieve thread-safety just wrap the work with CancellationTokonSource in the lock statement? Like that:

CancellationTokenSource cts;
readonly object ctsSync = new object();
        
async void OnConnected() 
{
    lock(ctsSync)
    {
        cts?.Cancel();
        var currentCts = cts = new CancellationTokenSource();   
    }

    try
    {
        var result = await LongRunningTask(currentCts.Token);
        //Do something with result if LongRinningTask was not cancelled
    }
    finally
    {
        currentCts.Dispose();               
    }
}
    

Is there better solution for these kind of problems?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
rustak
  • 11
  • 2
  • Take a look at the `CancelableExecution` class in [this answer](https://stackoverflow.com/questions/6960520/when-to-dispose-cancellationtokensource/61681938#61681938 "When to dispose CancellationTokenSource?"). It might be what you want. – Theodor Zoulias Apr 20 '23 at 17:59
  • 1
    That is exactly what I was looking for but couldn't figure out by myself. I would mark it as the accepted answer but its a comment. Thanks. – rustak Apr 23 '23 at 15:37

0 Answers0