title: How do to asynchronous I/O bound work correctly
body: <p>I want to fully understand how to implement the async and await keywords in TAP. I came around this MSDN entry: <a href="https://docs.microsoft.com/en-us/dotnet/csharp/async" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/dotnet/csharp/async</a></p>
  <p>In this post you can read the following two statements:</p>
  <blockquote>
  <p>For I/O-bound code, you await an operation that returns a Task or Task inside of an async method.</p>
  </blockquote>
  <blockquote>
  <p>Here are two questions you should ask before you write any code:</p>
  <p>Will your code be &quot;waiting&quot; for something, such as data from a database?</p>
  <p>If your answer is &quot;yes&quot;, then your work is I/O-bound.</p>
  <p>Will your code be performing an expensive computation?</p>
  <p>If you answered &quot;yes&quot;, then your work is CPU-bound.</p>
  </blockquote>
  <blockquote>
  <p>If the work you have is I/O-bound, use async and await without Task.Run. You should not use the Task Parallel Library. The reason for this is outlined in Async in Depth.</p>
  </blockquote>
  <p>The linked article is <a href="https://docs.microsoft.com/en-us/dotnet/standard/async-in-depth" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/dotnet/standard/async-in-depth</a></p>
  <p>But I don't get it, why I shouldn't use Task.Run for fetching data from a database.</p>
  <p>I mean for the most methods I can simply use the Async counter part such as <code>ExecuteNonQueryAsync</code> or <code>ExecuteScalarAsync</code></p>
  <p>But how should I use a data adapter to fetch a DataTable. Consider the following method</p>
  <pre><code>public DataTable SelectData(string selectCommand)
  {
      OpenConnection();
      DataTable data = new DataTable();
      Command.CommandType = CommandType.Text;
      Command.CommandText = selectCommand;
  
      using (MySqlDataAdapter adapter = new MySqlDataAdapter(Command))
      {
          adapter.Fill(data);
      }
      CloseConnection();
      return data;
  }
  </code></pre>
  <p>I would suggest the following method to get my data async, but I don't know whether this is the right way according to the post on MSDN.</p>
  <pre><code>public async Task&lt;DataTable&gt; SelectDataAsync(string selectCommand)
  {
      return await Task.Run(() =&gt; SelectData(selectCommand));
  }
  </code></pre>
  <p>Moreover, consider the following method:</p>
  <pre><code>public void Query(string sqlCommand)
  {
      OpenConnection();
      Command.CommandText = sqlCommand;
      Command.CommandType = CommandType.Text;
      Command.ExecuteNonQuery();
      CloseConnection();
  }
  </code></pre>
  <p>How would I write this method if I want to support both Async and synchronous? I mean I could write the same code twice but instead of calling the synchrounous method, I use the async one.</p>
  <pre><code>public async QueryAsync(string sqlCommand)
  {
      OpenConnection();
      Command.CommandText = sqlCommand;
      Command.CommandType = CommandType.Text;
      await Command.ExecuteNonQueryAsync();
      CloseConnection();
  }
  </code></pre>
  <p>Again, the same scenario. I shouldn't use Task.Run for I/O-Bound work but I do not want to write almost the same code twice.</p>
  <p>Could anyone clarify how to do this correctly?</p>