1

I have C# WPF application which reads data from database then does some work. But the problem is when I am reading data my UI doesn't respond. I have tried Tasks and dispatcher. None of them helps. Code below is in the button_click event. Here is code:

DataSet ds;
DataTable dt = new DataTable();

Task myTask = new Task(new Action(() =>
{
     //GetMyDataSet() returns DataSet
     ds = GetMyDataSet();
     dt = ds.Tables["MyTableName"];
}));

myTask.Start();

while (!myTask.IsCompleted)
{
    System.Threading.Thread.Sleep(1000);
}

//Continue
3
  • 4
    Why are you sleeping on the UI thread until the task completes? That's why your UI is unresponsive! Commented Jun 7, 2012 at 12:34
  • 1
    I think you should use BackgroundWorker. Commented Jun 7, 2012 at 12:36
  • @NikhilAgrawal can you recomend me any site which introduces BackroundWorker briefly? Commented Jun 7, 2012 at 12:46

2 Answers 2

7

First off, get rid of the sleep-spin, it completely defeats the purpose of using a Task since it doesn't allow the UI thread to proceed until the Task completes. You don't want that!

Task myTask = Task.Factory.StartNew(
     new Action(() =>
     {
         DataSet ds;
         DataTable dt = new DataTable();    

         //GetMyDataSet() returns DataSet
         ds = GetMyDataSet();
         dt = ds.Tables["MyTableName"];

         // use Invoke/BeginInvoke to update UI
      }));

Now your task will run in parallel with the UI thread until completion. At the end of the Task code use Dispatcher.BeginInvoke to update the UI. It should be ok now.

Sign up to request clarification or add additional context in comments.

5 Comments

I can't use Task.Factory.StartNew(). Am I missing reference or what is problem?
System.Threading.Tasks.Task.Factory' is a 'property' but is used like a 'type'
@Adil Mammadov: This is very strange. Can you update the code in the question with what you have now?
And if you'd like a bit different approach, instead of using the Dispatcher at the end, you can use task continuation with TaskScheduler.FromCurrentSynchronizationContext. :) After you solve your TPL problems, of course.
I did What same Task myTask = new Task.Factory.StartNew(). But I deleted Thread.Sleep() and wrote logic which I used to read data from DataTable in the same Task. Everything works fine now. Thank you
-2

Try

while (!myTask.IsCompleted)
{
    Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
    System.Threading.Thread.Sleep(20);
}

3 Comments

This is just wrong. The reason for the UI freezing is exactly this while loop which should not exist.
But he wants the UI to keep responding while the Task is working, not block.
Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })) simulates "Application.DoEvents" and UI become accessible (process events) every 20 ms. Try simple button handler: private void button1_Click(object sender, RoutedEventArgs e) { while (true) { Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { })); Thread.Sleep(20); } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.