Reputation: 21855
We are having multiple issues with this exception but I cannot find technical documentation about the real cause of the issue, all the possible sources for this error and what should we avoid to avoid having the exception.
I have read the following:
The dispatcher processing is suspended to avoid reentrancy problems when updating the visual tree.
But I'm unsure about what means 'updating the visual tree' and what causes a message to be sent to the Dispatcher and reproduces the issue.
The following sample code reproduces the issue:
XAML
<Window x:Class="SuspendedPOF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<StackPanel>
<Button Content="1" x:Name="Button1" IsVisibleChanged="Button1_OnIsVisibleChanged" />
</StackPanel>
</Window>
C# Code
using System.Windows;
namespace SuspendedPOF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button1_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
MessageBox.Show("Hello");
}
}
}
The MessageBox call is not the only one that fires this exception, things like Focus sometimes are problematic as well.
Any help would be great.
Upvotes: 5
Views: 7579
Reputation: 21855
As far as I know there is no way to know when you are handling an event that can modify the visual state of the control nor there is a way knowing if your actions will modify the visual state of the UI so it is just a matter of putting BeginInvoke()
calls whenever you find a crash ... :S
Upvotes: 0
Reputation: 5666
The point is that potentially you are trying to change the visual state of your button in the event handler which manages its visual changes (i.e. its visibility). This could lead to an infinite loop (a "reentrancy problems" as you read) and this is also the reason of the InvalidOperationException
, that you obtain.
To avoid this issue, you have to defer the MessageBox
opening by using the Dispatcher. Then in the Button1_OnIsVisibleChanged
method, use this code:
Dispatcher.BeginInvoke(new Action(() => System.Windows.MessageBox.Show("Hello")),
System.Windows.Threading.DispatcherPriority.Normal);
instead of directly calling the MessageBox.Show()
static method.
Upvotes: 5