MaterialDesignInXamlToolkit
MaterialDesignInXamlToolkit copied to clipboard
DialogHost can throw exception when opening and closing dialog in quick succession
DialogHost can throw exception when opening and closing dialog in quick succession.
Background
I have a view which is password protected. The password dialog is shown when the user opens the view. The dialog is using a DialogHost
placed on the view and is the only "client" of the dialog host. If the user navigates away from the view, the dialog will be closed.
Problem
If the dialog is shown and the user navigates away from the view shortly after there is a chance that the DialogHost
will throw a NullReferenceException
.
2018-10-04 09:02:10.870 +02:00 [Error ] [02] Unhandled exception occurred. Origin=System.Threading.Tasks.TaskScheduler.UnobservedTaskException,
System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at MaterialDesignThemes.Wpf.DialogHost.<>c__DisplayClass38_1.<IsOpenPropertyChangedCallback>b__2(Task t) in C:\projects\materialdesigninxamltoolkit\MaterialDesignThemes.Wpf\DialogHost.cs:line 296
at System.Threading.Tasks.ContinuationResultTaskFromTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object.
at MaterialDesignThemes.Wpf.DialogHost.<>c__DisplayClass38_1.<IsOpenPropertyChangedCallback>b__2(Task t) in C:\projects\materialdesigninxamltoolkit\MaterialDesignThemes.Wpf\DialogHost.cs:line 296
at System.Threading.Tasks.ContinuationResultTaskFromTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()<---
My guess is that since there is a delay when opening a dialog it is possible that some reference become null
during the delay. I think that the child
variable should not change value but it could be possible that its Dispatcher
property becomes null
when the object is removed from visual tree or something like that.
Anyway, the code might need some more protective null
checking.
dialogHost.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
CommandManager.InvalidateRequerySuggested();
UIElement child = dialogHost.FocusPopup();
if (child != null)
{
//https://github.com/ButchersBoy/MaterialDesignInXamlToolkit/issues/187
//totally not happy about this, but on immediate validation we can get some weird looking stuff...give WPF a kick to refresh...
Task.Delay(300).ContinueWith(t => child.Dispatcher.BeginInvoke(new Action(() => child.InvalidateVisual())));
}
}));
see DialogHost.cs