title: When to use Task.Run and not
body: <p>I asked this <a href="https://stackoverflow.com/questions/51386881/task-iscompleted-not-returning-correct-task-state">question</a> yesterday and still don't understand the difference in using </p>
  
  <pre><code>task = Task.Run(() =&gt; RunLongRunningMethod(cts.Token));
  </code></pre>
  
  <p>and</p>
  
  <pre><code>task = RunLongRunningMethod(cts.Token);
  </code></pre>
  
  <p>I've read through <a href="https://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html" rel="nofollow noreferrer">Task.Run Etiquette and Proper Usage</a> and it appears to be mostly using Task.Run as long as it's used correctly (not in the implementation) </p>
  
  <p>Is there any other reading material about this and or can someone explain the difference between the two?</p>
  
  <p>My code is below which works okay using both methods.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Diagnostics;
  using System.Drawing;
  using System.Linq;
  using System.Net;
  using System.Net.Http;
  using System.Net.Http.Headers;
  using System.Text;
  using System.Threading;
  using System.Threading.Tasks;
  using System.Windows.Forms;
  
  namespace WindowsFormsApp1
  {
      public partial class Form1 : Form
      {
          private static HttpClient client { get; set; }
          private Task task { get; set; }
          private CancellationTokenSource cts { get; set; }
          private bool buttonStartStopState { get; set; }
  
          public Form1()
          {
              InitializeComponent();
          }
  
          private async Task RunLongRunningMethod(CancellationToken cancellationToken)
          {
              try
              {
                  while (true)
                  {
                      if (cancellationToken.IsCancellationRequested)
                      {
                          cancellationToken.ThrowIfCancellationRequested();
                      }
  
                      // Some CPU bound work here
  
                      // Then call async
                      var success = await GetUrlAsync(@"https://www.bbc.co.uk/");
                      Thread.Sleep(2000); // simulate blocking only
                  }
              }
              catch (OperationCanceledException)
              {
                  // Just exit without logging. Operation cancelled by user.
              }
              catch (Exception ex)
              {
                  // Report Error
              }
          }
  
          private async Task&lt;bool&gt; GetUrlAsync(string url)
          {
              if (client == null)
              {
                  client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true, AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip });
                  client.BaseAddress = new Uri("https://www.bbc.co.uk/");
                  client.DefaultRequestHeaders.Add("Accept", "*/*");
                  client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
                  client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/62.0");
                  client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
                  client.DefaultRequestHeaders.Add("DNT", "1");
              }
  
              var response = await client.GetAsync(url);
              var contents = await response.Content.ReadAsStringAsync();
  
              Debug.WriteLine($"{DateTime.Now} {response.StatusCode}");
              return true;
          }
  
          private void buttonStartStop_Click(object sender, EventArgs e)
          {
              buttonStartStopState = !buttonStartStopState;
              if(buttonStartStopState)
              {
                  cts = new CancellationTokenSource();
  
                  // What is difference between this
                  //task = Task.Run(() =&gt; RunLongRunningMethod(cts.Token));
  
                  // And this?
                  task = RunLongRunningMethod(cts.Token);
  
                  // This always runs instantly
                  Debug.WriteLine($"{DateTime.Now} buttonStartStopState:{buttonStartStopState}");
              }
              else
              {
                  cts.Cancel();
                  cts = null;
              }
          }
  
          private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
          {
              if(cts != null)
              {
                  cts.Cancel(); // CancellationTokenSource
                  cts = null;
              }
  
              if (!task.IsCompleted)
              {
                  //this.Hide();
                  e.Cancel = true;
                  await task;
                  this.Close();
              }
          }
      }
  }
  </code></pre>