title: Control and cancel multiple tasks
body: <p>I've tried to code simple WinForm app, and i have some problem with its behavior.
  The purpose is to draw small rectangles on the panel with two optional colors (red &amp; black). There is 4 buttons - pair for each color - <strong>Draw red</strong>, <strong>Stop red</strong>, <strong>Draw black</strong>, <strong>Stop Black</strong>.</p>
  
  <p>When the <strong>Draw</strong> button clicked, new task of <strong>DrawRectangles</strong> is generated.
  When the <strong>stop</strong> button clicked, the task will be cancelled, using CancellationTokenSource.</p>
  
  <p>The problem is: when i've created many tasks (i.e 3 tasks of Draw red) and after that i pressed on stop button, it canceled just the first task and I could not cancel the other tasks (Draw red tasks') and they ran endless.</p>
  
  <p>The code below: </p>
  
  <pre><code>public partial class Form1 : Form
  {
      CancellationTokenSource cnDrawRedToken;
      CancellationTokenSource cnDrawBlackToken;
      public Form1()
      {
          InitializeComponent();          
      }
  
      private void Form1_Load(object sender, EventArgs e{}
  
      private void panel1_Paint(object sender, PaintEventArgs e){}
  
      private void RedBtn_Click(object sender, EventArgs e)
      {
          RunDrawingTask(SetSpecificPen(Color.Red),out this.cnDrawRedToken);           
      }
  
      private async Task DrawRectangles(int height, int width, Random random, Rectangle rectangle, Pen blackPen, CancellationToken cnToken)
      {
          while(true)
          {
              if (cnToken.IsCancellationRequested)
                  return;
              rectangle.x = random.Next(0, width);
              rectangle.y = random.Next(0, height);
              this.panel1.CreateGraphics().DrawRectangle(blackPen, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
              //Thread.Sleep(200);
              await Task.Delay(150);
          }
      }
  
      private Pen SetSpecificPen(Color color)
      {
          Pen blackPen = new Pen(color, 2);
          return blackPen;
      }
  
      private Rectangle InitRectangleWidthAndHeights()
      {
          Rectangle rectangle = new Rectangle();
  
          rectangle.width = 10;
          rectangle.height = 10;
          return rectangle;
      }
  
      private void StpRedBtn_Click(object sender, EventArgs e)
      {
          if (this.cnDrawRedToken != null)
          {
              this.cnDrawRedToken.Cancel();
              this.cnDrawRedToken = null; 
          }
          else
          {
              this.cnDrawRedToken = new CancellationTokenSource();
          }
      }
  
      private void BlackBtn_Click(object sender, EventArgs e)
      {
          RunDrawingTask(SetSpecificPen(Color.Black),out this.cnDrawBlackToken);
      }
  
      private void StpBlkBtn_Click(object sender, EventArgs e)
      {
          if (this.cnDrawBlackToken != null)
          {
              this.cnDrawBlackToken.Cancel();
              this.cnDrawBlackToken = null; 
          }
      }
  
      private void RunDrawingTask(Pen specificPen, out CancellationTokenSource cnTokenSource) 
      {
          int height = this.panel1.Height;
          int width = this.panel1.Width;
          Random random = new Random();
          Rectangle rectangle = InitRectangleWidthAndHeights();
  
          cnTokenSource = new CancellationTokenSource();
          CancellationTokenSource cts = cnTokenSource;
          Task t = Task.Factory.StartNew(() =&gt; DrawRectangles(height, width, random, rectangle, specificPen, cts.Token), cts.Token);
      }
  }
  </code></pre>
  
  <p>What i want to do is when i click on <strong>Stop</strong> button all the running tasks of the same color will be cancelled.</p>
  
  <p><strong>UPDATE:</strong>
  As Fabio suggested, i've rewrote my click's methods as well as the affected methods. After that chenges it works as desired. </p>
  
  <pre><code>public Form1()
      {
          InitializeComponent();
          cnDrawRedToken = new CancellationTokenSource() ;
          cnDrawBlackToken = new CancellationTokenSource();
      }
   private void RedBtn_Click(object sender, EventArgs e)
      {
          if (this.cnDrawRedToken.IsCancellationRequested)
          {
             this.cnDrawRedToken = null;
             this.cnDrawRedToken = new CancellationTokenSource();
          }           
          RunDrawingTask(SetSpecificPen(Color.Red), this.cnDrawRedToken);           
      }
  private void StpRedBtn_Click(object sender, EventArgs e)
      {
          if (this.cnDrawRedToken != null)
          {
              this.cnDrawRedToken.Cancel();
          }          
      }
  
      private void BlackBtn_Click(object sender, EventArgs e)
      {
          if (this.cnDrawBlackToken.IsCancellationRequested)
          {
              this.cnDrawBlackToken = null;
              this.cnDrawBlackToken = new CancellationTokenSource();
          }             
          RunDrawingTask(SetSpecificPen(Color.Black), this.cnDrawBlackToken);
      }
  
      private void StpBlkBtn_Click(object sender, EventArgs e)
      {
          if (this.cnDrawBlackToken != null)
          {
              this.cnDrawBlackToken.Cancel();                
          }
      }
  
      private void RunDrawingTask(Pen specificPen, CancellationTokenSource cnTokenSource) 
      {
          int height = this.panel1.Height;
          int width = this.panel1.Width;
          Random random = new Random();
          Rectangle rectangle = InitRectangleWidthAndHeights();
  
          Task t = Task.Factory.StartNew(() =&gt; DrawRectangles(height, width, random, rectangle, specificPen, cnTokenSource.Token), cnTokenSource.Token);
      }
  </code></pre>