Search code examples
c#cancellationcancellationtokensourcecancellation-token

Know which CancellationToken failed in CreateLinkedTokenSource to evaluate weird cancellationRequested behavior


I have the following code

Class Class1
{
    Class2 class2 = new Class2();
    CancellationToken first = new CancellationToken();
    CancellationToken second = new CancellationToken();
    CancellationTokenSource cts=
              CancellationTokenSource.CreateLinkedTokenSource(first, second))
    class2.OpenSocketAndRead(cts.Token);
}

Class Class2
{
   public void OpenSocketAndRead(CancellationToken ct)
   {
       try
       {
          await websocket.ReceiveAsync(new ArraySegment<byte>(buffer, receivedBytes, availableBytes), ct).ConfigureAwait(false);
       }
       catch (WebSocketException e)
       {
           ct.ThrowIfCancellationRequested();
           var message = this.ConstructErrorMessage("Error during read.", ct);
           throw new CustomException(message);
       }
   }

   private string ConstructErrorMessage(String m, CancellationToken ct)
   {
       StringBuffer sb = new StringBuffer();
       sb.append(m);
       if(ct.IsCancellationRequested)
       {
           sb.append("WHICH TOKEN FAILED");
       }
   } 
}    

I experienced this weird behavior where ct didnotthrow and the flow came to ConstructErrorMessage where ct.IsCancellationRequested evaluates to true. The Websocket error code is ConnectionClosedPrematurely.

I want to know which token failed inside ConstructErrorMessage and why the ThrowIfCancellationRequested did not execute.


Solution

  • I experienced this weird behavior where ct didnotthrow and the flow came to ConstructErrorMessage where ct.IsCancellationRequested evaluates to true.

    That's entirely possible - it means the CancellationToken was cancelled after the call to ThrowIfCancellationRequested and before the call to IsCancellationRequested.

    I want to know which token failed

    This is not possible in the general case, due to linked tokens. However, your code can examine which tokens are cancelled, and for all practical considerations, that's usually good enough.