+1  A: 

Have you tried putting a

Application.DoEvents()

in here

if (dlgRes == DialogResult.Yes)
{
   Application.DoEvents(); 
   ProcessAllUpdates(um2); 
}
KiwiBastard
+3  A: 

Your UI isn't updating because all the work is happening in the user interface thread. Your call to:

this.BeginInvoke((MethodInvoker)delegate() {update.Action.Run(); })

is saying invoke update.Action.Run() on the thread that created "this" (your form), which is the user interface thread.

Application.DoEvents()

will indeed give the UI thread the chance to redraw the screen, but I'd be tempted to create new delegate, and call BeginInvoke on that.

This will execute the update.Action.Run() function on a seperate thread allocated from the thread pool. You can then keep checking the IAsyncResult until the update is complete, querying the update object for its progress after every check (because you can't have the other thread update the progress bar/UI), then calling Application.DoEvents().

You also are supposed to call EndInvoke() afterwards otherwise you may end up leaking resources

I would also be tempted to put a cancel button on the progress dialog, and add a timeout, otherwise if the update gets stuck (or takes too long) then your application will have locked up forever.

John Sibly
+1  A: 

@ John Sibly

You can get away with not calling EndInvoke when dealing with WinForms without any negative consequences.

The only documented exception to the rule that I'm aware of is in Windows Forms, where you are officially allowed to call Control.BeginInvoke without bothering to call Control.EndInvoke.

However in all other cases when dealing with the Begin/End Async pattern you should assume it will leak, as you stated.

Quibblesome