title: Task.IsCompleted stays false even when CancelIsRequested
body: <p>In my LogManager, I have an async task that runs a while loop to write log information to a text file (and add it to a collection). When I try to cancel this task, the loop seems to stop (I tried with several Console.WriteLines), but the task however doesn't complete.</p>
  
  <p>Here are the main methods of this class:</p>
  
  <pre><code>public static DateTime StartTime;
  private static CancellationTokenSource SaveLoopToken;
  private static Task SaveLoopTask;
  
  public static void Start()
  {
      LogMessage startMessage = new LogMessage("Logging Started");
      startMessage.SetCaller("StartLogging", "LogManager");
      StartTime = startMessage.Time;
      LogQueue.Post(startMessage);
      StartSaveLoop();
  }
  
  public static void Stop()
  {
      LogMessage stopMessage = new LogMessage("Logging Stopped");
      stopMessage.SetCaller("StopLogging", "LogManager");
      LogQueue.Post(stopMessage);
      StopSaveLoop();
  }
  
  private static void StartSaveLoop()
  {
      SaveLoopToken = new CancellationTokenSource();
      SaveLoopTask = SaveLoop(SaveLoopToken);
      Console.WriteLine("Loop started!");
  }
  
  private static void StopSaveLoop()
  {
      Console.WriteLine("Stop requested");
  
      SaveLoopToken.Cancel();
  
      while (!SaveLoopTask.IsCompleted)
      {
          Thread.Sleep(100);
      }
  
      Console.WriteLine("Loop stopped!");
  }
  
  private static void AddLogToCollection(LogMessage logMessage)
  {
      // Add to MessageList
      MessageList.Add(logMessage);
  
      // Add to CurrentMessageList
      CurrentMessageList.Add(logMessage);
  
      // Add to FilteredMessageList
      if (logMessage.Level &gt;= FilterLevel)
      {
          FilteredMessageList.Add(logMessage);
      }
  }
  
  private static async Task SaveLoop(CancellationTokenSource cancel)
  {
      string logPath = "logs\\";
      string logFile = StartTime.ToString("yyyy-MM-dd_HH-mm-ss") + ".log";
      string fullPath = Path.Combine(logPath, logFile);
  
      if (!Directory.Exists(logPath))
          Directory.CreateDirectory(logPath);
  
      using (FileStream fileStream = new FileStream(fullPath, FileMode.Append, FileAccess.Write, FileShare.Read, 8192, useAsync: true))
      {
          using (StreamWriter writer = new StreamWriter(fileStream))
          {
              while (true)
              {
                  LogMessage logMessage = await LogQueue.ReceiveAsync(cancel.Token);
  
                  AddLogToCollection(logMessage);
  
                  await writer.WriteAsync(String.Format("({0}) ", logMessage.LogID));
                  await writer.WriteAsync(String.Format("[{0}][{1}] ", logMessage.Time.ToString("HH:mm:ss:fff"), logMessage.Level.ToString()));
                  await writer.WriteAsync(logMessage.Message);
                  await writer.WriteLineAsync(String.Format(" ({0} - {1})", logMessage.Method, logMessage.Location));
  
                  if (cancel.IsCancellationRequested)
                      break;
              }
          }
      }
  }
  </code></pre>
  
  <hr>
  
  <p>Previous Start/StopSaveLoop methods:</p>
  
  <pre><code>private static async void StartSaveLoop()
  {
      SaveLoopToken = new CancellationTokenSource();
      Console.WriteLine("Loop started!");
  
      await SaveLoop(SaveLoopToken);
      Console.WriteLine("Loop stoped!");
  }
  
  private static void StopSaveLoop()
  {
      Console.WriteLine("Stop requested");
      SaveLoopToken.Cancel();
  }
  </code></pre>