-1

My question is how to update UI controls (such as ProgressBar) from another thread while UI thread is busy for querying the database (running a time-consuming stored procedure) ?


I checked these questions and still no solution is found for me.

  1. Updating UI continuously while the main thread is busy
  2. How to update the GUI from another thread in C#?
  3. Run multiple UI Threads
  4. Cross-thread cross-form. Display a splash screen with a progress bar

I know one option is to do time-consuming work using BackgroundWorker and update ProgressBar using ReportProgress method, but I have a problem in this option because the UI thread is responsible for instantiate and show another form after querying the database like this:

Form2 f2=new Form2();
f2.show();
Community
  • 1
  • 1
oMiD
  • 322
  • 4
  • 20
  • 1
    I am also querying database in main UI thread + filling views (wpf), so this part is ok. And the problem is - you can not update that UI because it's busy. There is [`DoEvents`](http://stackoverflow.com/q/5181777/1997232) which you can use, but I found what another window in another thread works the best. Well, at least it was for me (but in wpf). See [further](http://stackoverflow.com/q/4793283/1997232). – Sinatr Jan 07 '16 at 16:03
  • I cannot figure out why you couldn't do anyway time-consuming on a secondary thread and then open the form on the main thread. Perhaps you should consider this before forcing UI refresh when the main thread is busy (if it is possible). – LucaMus Jan 07 '16 at 16:05
  • 1
    you've just pointed out your flaw. Never query a database from the main UI thread! – Mark Lakata Jan 07 '16 at 16:18

1 Answers1

4

I recommend you use BackgroundWorker and put the construction and presentation of the Form2 object in the BackgroundWorker's RunWorkerCompleted event handler, which executes on the UI thread when the BackgroundWorker is finished. Definitely don't try to update the UI from a background thread. The GUI classes are not threadsafe.

adv12
  • 8,443
  • 2
  • 24
  • 48
  • thanks for answer, What is your advice for the situation in which the time-consuming work is showing Form2 and I still need to update ProgressBar of main form during that work? – oMiD Jan 07 '16 at 18:05
  • 1
    So you're saying that the "time-consuming work" requires user input mid-execution? There are ways to deal with that as well. `Control.Invoke` will let you run code on the GUI thread while blocking the calling thread. – adv12 Jan 07 '16 at 18:40
  • We can assume login form for my scenario; user inputs username and pass, I check login info and show Form2, but the Form2 is UI-rich and takes 10-12 seconds to load, during this, I want to update ProgressBar in main form, am I clear? – oMiD Jan 07 '16 at 18:47
  • 1
    If Form2 takes that long to load purely because it has that many controls (doubtful), there's really nothing you can do. All the work has to be done on the UI thread, so your UI thread has to wait. If, instead, Form2 is doing a lot of IO or something not tied to the GUI in its initialization, you could put that work on background threads too. – adv12 Jan 07 '16 at 18:51