views:

109

answers:

3

I am attempting to use a Microsoft.SqlServer.Management.Smo.Restore object to restore a SQL Server 2000 database. Just before I begin the restore operation, I change the text of a label so that the user knows what is going on. However, the changed text isn't visible on the GUI (i.e., the text remains the same as it was) until AFTER the fullRestore.Wait() line.

lblStatus.Text = "Restoring Database";
Restore fullRestore = new Restore(); 

// Configure fullRestore

fullRestore.SqlRestore(_server);
fullRestore.Wait();

The weird thing is, lblStatus eventually does display "Restoring Database", but not until after the restore is complete. Any ideas?

A: 

It's a threading issue. You can do this on seperate threads or on a background thread. One approach I've seen people use is do a Application.DoEvents() although I typically stay away from that call.

Cody C
+2  A: 

You're blocking on the GUI thread, which is preventing it from updating. You can call lblStatus.Refresh(), or move your Wait to a background thread (which is ultimately the right thing to do).

Jon B
Calling lblStatus.Refresh() won't make any difference, all that does is invalidates the control so it will get repainted, the actual repaint still can't happen until the GUI thread is available.
Simon P Stevens
@Simon - it repaints before the call that is locking the GUI thread.
Jon B
Interesting, I just tried lblStatus.Refresh() and it does exactly what I need it to. I know that a background thread for Wait() would be a better solution but this is simple enough and works for right now.
Donut
Jon is right; that's the difference between Control.Invalidate() and Control.Refresh(); refresh first calls Invalidate and then forces an update.
Fredrik Mörk
Hmmm. That is very interesting. I'm happy to admit I am clearlly totally wrong on this. I had thought that as the code was actually running on the foreground thread there would be no moment that the update could occur. I think Fredrik is right, I hadn't realised that refresh actually performs the update. My mistake.
Simon P Stevens
A: 

The update to the GUI cannot occur until you have finished processing on the foreground thread and released it. You need to do the restore on a background thread to allow the foreground thread to continue updating the GUI. Consider putting the restore code in a separate method and using ThreadPool.QueueUserWorkItem( ), and passing the restore method. This will trigger your restore method on a thread pool thread.

If you need more control over the thread and notification when it has finished, you can use a BackgroundWorker

Simon P Stevens