0

I am having a problem with updating the Window of a Wpf-Application. After googling a long time, I broke my problem down to the following example. I hope you can help me.

Let´s say we have a Window with a Button and a TextBlock ... nothing special:

...
<Grid>
  <Button ... Click="button_Click"/>
  <TextBox x:Name="textBox" Text="DefaultText" .../>
</Grid>
...

The button_Click is a simple event like this:

private void button_Click(object sender, RoutedEventArgs e)
{
  for (int i = 0; i < 20; i++)
  {
    textBox.Dispatcher.Invoke(new Action(() => textBox.Text = i.ToString());
  }
}

And here is my Problem. If I debug the loop, the Text of my TextBlock is always the "DefaultText". Only at the end of my loop, the Text is "19". Why is my dispatcher not able to change the Text? Like described here (What's the difference between Invoke() and BeginInvoke()) the Dispatcher should stop my Thread until the job is done. I tried different DispatcherPriorities ... but no difference. What´s my problem?

Thank you for helping me.

Community
  • 1
  • 1
Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
  • 2
    It's not to slow but your loop runs on UI thread and blocks it – dkozl Jan 25 '16 at 19:15
  • 2
    Your `button_Click` runs on the main UI thread (Priority Normal, so 9), so issues commands for 20 updates, then ends. Afterwards, the 20 commands get executed, all on the same priority level (I think `Send`, which is 10), then completes. And finally, `DispatcherPriority.Render` runs (priority 7), and updates the UI to whatever the last item was. I'm not sure what you're trying to accomplish here, however if you let us know perhaps we can offer you a better solution. – Rachel Jan 25 '16 at 19:18
  • So far, so good. But how can I achieve to render my UI after each command, to show the real Text of my TextBlock? - Thank you for helping me! – Fruchtzwerg Jan 25 '16 at 19:22
  • 2
    @Fruchtzwerg The timing is so quick it would not really be noticeable. You could try running the TextBox update at a lower dispatcher priority than Render, such as Background (4). I also wanted to mention you may want to do a `Debug.WriteLine to verify the value of `i` at the time the action executes. I think `i` will always be 19 because by the time the code executes the Action, `i` will have gone through all iterations and will be at 19. If that is the case, you probably need to move it to a temp value in the loop, such as `int temp = i;` and use `temp` in your Action. – Rachel Jan 25 '16 at 20:10

1 Answers1

0

For anyone googling around looking for a solution to their slow WPF application during debugging;

When instantiating the DispatcherTimer object use DispatcherPriority.Send as an argument. This sets the priority of your UI higher, making your application or game run smoother while debugging. Source

DispatcherTimer gameTimer = new DispatcherTimer(DispatcherPriority.Send);

I hope this will help out someone else in the future :)

Maarten
  • 402
  • 5
  • 20