Reputation: 1051
I have the following code:
label1.content = "Start";
bool a = executeLongTask();
label1.content = "Done";
For some reason the label only gets updated to "Done" after the executeLongTask() method is completed. It completely skips displaying the "Start" message.
Why is the label not being set to "Start" when the application is running and how would I make it update to "Start" first without using multiple threads?
The executeLongTask() method by the way calls a PowerShell script and awaits it output before proceeding onto label1.content = "Done";
Upvotes: 1
Views: 4824
Reputation: 21
Have simple solution see below:
Solution 1:
label1.Dispatcher.Invoke(new Action(()=> { label1.content = "Message"; }), System.Threading.DispatcherPriority.Background);
Solution 2: 1.Add "System.Windows.Forms" namespace in reference section 2.Write as below:
label1.content = "Message"; System.Windows.Forms.Application.DoEvents();
Upvotes: 1
Reputation: 456387
For some reason the label only gets updated to "Done" after the executeLongTask() method is completed. It completely skips displaying the "Start" message.
That's because the UI thread needs to return to its main loop in order to process WM_PAINT
updates. When you set the label the first time, WPF makes a note that it should redraw the label when it returns to the message processing loop. Then the UI is kept busy in the executeLongTask
method, and then the label is set the second time, and WPF again makes a note that it should redraw the label. When you return control to the UI message loop, it finally gets a chance to actually do the redraw and update what you see on the screen.
how would I make it update to "Start" first without using multiple threads?
The easiest solution is to use multiple threads. Example:
label1.content = "Start";
bool a = await Task.Run(() => executeLongTask());
label1.content = "Done";
Alternatively, you could rewrite executeLongTask
to act asynchronously, and then you wouldn't need a separate thread:
label1.content = "Start";
bool a = await executeLongTaskAsync();
label1.content = "Done";
Upvotes: 7
Reputation: 108
The text will only update after the function returns. If you want it to update while executeLongTask()
is running you need to use the async/await pattern. The will let you return control until the long task completes.
Upvotes: 1