title: How to show loading dialog while a long time query is executed?
body: <p>I created a winforms app with .net 4.0.</p>
  
  <p>First, I created a LoadingForm with cancel button, that must stop execution query.</p>
  
  <p>I want to create an <code>ExecuteHelper</code> class and <code>LoadingForm</code> with cancellation query button.</p>
  
  <pre><code>public partial class LoadingFrm : DevExpress.XtraEditors.XtraForm
  {
      private Action _cancel;
  
      public LoadingFrm(Action a)
      {
          _cancel = a;
          InitializeComponent();
          this.FormBorderStyle = FormBorderStyle.None;
      }
  
      private void simpleButton1_Click(object sender, EventArgs e)
      {
          this.close();
          _cancel();
      }
  }
  </code></pre>
  
  <p>Then, I create an <code>ExecuteHelper</code> class:</p>
  
  <pre><code>public class ExecuteHelper
  {
      private readonly int tOut = 1000;
      private LoadingFrm _loadFrm;
      private SqlDataReader _result;
      private Task worker;
      private CancellationTokenSource cts;
      private IAsyncResult iAr;
      private SqlCommand _command;
  
      ExecuteHelper()
      {
          _loadFrm = new LoadingFrm(CancelExecution);
      }
  
      public SqlDataReader Execute(SqlCommand command)
      {
          _command = command;
          cts = new CancellationTokenSource();
          var cToken = cts.Token;
          cts.Token.Register(() =&gt; _loadFrm.Invoke((MethodInvoker)delegate() { _loadFrm.Close(); }));
          worker = new Task(() =&gt; { _loadFrm.ShowDialog(); }, cToken);
          SqlDataReader r = null;
          worker.Start();
  
          iAr = command.BeginExecuteReader();
  
          while (!iAr.IsCompleted)
          {
          }
  
          r = command.EndExecuteReader(iAr);
          cts.Cancel();
          return r;
      }
  
      public void CancelExecution()
      {
          _command.EndExecuteReader(iAr);
      }
  }
  </code></pre>
  
  <p>Something is wrong, and it does not show the desired effect. Can anybody help?</p>
  
  <p>Maybe this solution is right:</p>
  
  <pre><code>public static SqlDataReader Execute(SqlCommand command)
  {
       var cts = new CancellationTokenSource();
       var cToken = cts.Token;
       cToken.Register(() =&gt; { command.Cancel(); });
  
       Task&lt;SqlDataReader&gt; query = new Task&lt;SqlDataReader&gt;(new Func&lt;SqlDataReader&gt;(() =&gt; { return command.ExecuteReader(); }), cToken);
       LoadingFrm _loadingF = new LoadingFrm(() =&gt; { cts.Cancel(); });
  
       new Action(() =&gt; { _loadingF.Show(); }).Invoke();
  
       query.Start();
       query.Wait(30000, cToken);
  
       query.ContinueWith((obj) =&gt;
       {
          _loadingF.Invoke((MethodInvoker)delegate
          {
              _loadingF.Close();
          });
       });
  
       return query.Result;
  }
  </code></pre>
  
  <p>Bur <code>query.start()</code> blocked the main thread and I can't click on button in loading form for cancel query execution.</p>