3

I'm currently filling my DataGridView using Tasks. At first, when I fill in dataTable, everything is fine, but when I continue to the UI thread, my form is unresponsive for a short time.

How can I avoid this unresponsive period?

if (bar == null)
{
    bar = CNPR.Controls.Helper.GetWaitingBar(this);
    this.Controls.Add(bar);
}
bar.Visible = true;
bar.BringToFront();
bar.StartWaiting();
panel1.Enabled = false;
rasteTableBindingSource.DataSource = null;
var t = Task.Factory.StartNew(() => rasteTableTableAdapter.FillBySearch(chapYarDataSet.rasteTable))
    .ContinueWith(delegate
    {
        bar.StopWaiting();
        bar.Visible = false;
        panel1.Enabled = true;
        rasteTableBindingSource.DataMember = chapYarDataSet.rasteTable.TableName;
        rasteTableBindingSource.DataSource = chapYarDataSet;
    }, TaskScheduler.FromCurrentSynchronizationContext());
VMAtm
  • 27,943
  • 17
  • 79
  • 125

1 Answers1

0

You're using the StartNew method with current synchronization context, so it's being run not in thread pool but on your ui. You should read the article by @StephenCleary StartNew is Dangerous for a better understanding of your code.

You should split your logic for a data retrieval, which should be done in background, by using the Run method, and fill the datasource in the ui context:

var t = Task.Run(() => rasteTableTableAdapter.FillBySearch(chapYarDataSet.rasteTable))
  .ContinueWith(delegate { /* UI logic here */ },
      TaskScheduler.FromCurrentSynchronizationContext());

Update: if you're using the .Net 4.0 and can't use the Run method, use this overload:

Task.Factory.StartNew({ /* Action here */ },
    CancellationToken.None,
    TaskCreationOptions.None,
    TaskScheduler.Default);

Another great article is Task.Run vs Task.Factory.StartNew

VMAtm
  • 27,943
  • 17
  • 79
  • 125