We have a main WinForms application that hosts WPF forms - these forms are started with their own dispatcher thread using this code:
if (Util.MultiThread) { // http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in-a-separate-thread-part-1/ // http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/ Thread thread = new Thread(() => { try { // Create the application object and load WPF resources Program.EnsureApplicationResources(); System.Windows.Window w = wpfForm(); System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(w); w.Show(); // When the main form OR window closes, shut down the dispatcher w.Closed += (s, ea) => w.Dispatcher.InvokeShutdown(); CommandInvoker.MainFormRef.FormClosing += (s, ea) => w.Dispatcher.InvokeShutdown(); System.Windows.Threading.Dispatcher.Run(); } catch (Exception ex) { ShowException(ex); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); }
One of our WPF forms frequently gets the error shown below and crashes, after which, the WPF form can no longer be opened and the application has to be restarted to restore this. We cannot produce this on demand, but it can happen several times a day. We have tried using v15.1.20151.2055, but the issue still occurs. None of our actual code is being accessed based on the stack trace, but Infragistics.Controls.Charts.XamDataChartView.OnTemplateProvided() seems to start the issues. Can some one explain what this class/method chain is doing that might cause this issue or something else that might be causing this.
Actual stack trace:
System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it. at System.Windows.DependencyObject.GetValue(DependencyProperty dp) at Infragistics.SafeSetter.Apply(DependencyObject target) at Infragistics.SafeSetterCollection.Apply(DependencyObject target) at Infragistics.SafeSetters.<.cctor>b__0(DependencyObject o, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.StyleHelper.ApplyStyleOrTemplateValue(FrameworkObject fo, DependencyProperty dp) at System.Windows.StyleHelper.InvalidateContainerDependents(DependencyObject container, FrugalStructList`1& exclusionContainerDependents, FrugalStructList`1& oldContainerDependents, FrugalStructList`1& newContainerDependents) at System.Windows.StyleHelper.DoStyleInvalidations(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle) at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache) at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args) at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value) at System.Windows.Data.BindingOperations.SetBinding(DependencyObject target, DependencyProperty dp, BindingBase binding) at Infragistics.Controls.SeriesViewerView.OnTemplateProvided() at Infragistics.Controls.Charts.XamDataChartView.OnTemplateProvided() at System.Windows.FrameworkElement.ApplyTemplate() at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV) at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged) at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV) at System.Windows.Controls.Grid.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV) at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged) at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV) at System.Windows.Controls.Grid.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV) at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV, Boolean& hasDesiredSizeUChanged) at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV) at System.Windows.Controls.Grid.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint) at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Documents.AdornerDecorator.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Controls.Border.MeasureOverride(Size constraint) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Window.MeasureOverrideHelper(Size constraint) at System.Windows.Window.MeasureOverride(Size availableSize) at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.Interop.HwndSource.SetLayoutSize() at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value) at System.Windows.Window.SetRootVisualAndUpdateSTC() at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight) at System.Windows.Window.CreateSourceWindow(Boolean duringShow) at System.Windows.Window.ShowHelper(Object booleanBox) at EnergyEndeavors.Util.<>c__DisplayClass8.<StartWPFWindow>b__4() in c:\Projects\VS_Infragistics_15.1\MontereyApp\EnergyEndeavors\Util.cs:line 110
Hi Andrew, we haven't made any progress on this so far. We have tried a few different things to try and get classes initialized before anything starts but to no avail. It seems as though there is some global object that gets initialized in one thread and stays alive for the life of the application -> once the user gets this error opening a screen, they will continue getting the error each time they try to open the screen until they close the entire application and re-open it (which is extremely costly due to the critical and large/complex nature of the application itself). Any thoughts on an object that is initialized once and stays in-scope even if the window containing the XamDataChart is closed?
We still don't have much to go on. A weird coincidence seems to be that this has happened more when a user's computer was re-booted from a Windows update - 3 users experienced this error all after being rebooted from a Windows update (and hence having to restart the app) - this has happened twice now, but I have not been able to simulate this and it seems to far removed from the actual app to be an actual trigger.
If you have any thoughts on a magical method call we can use to pre-initialize objects, please let me know (I tried this.show() right after the InitializeComponent() call in he constructor for the window containing the control to try and force any one-shot initialization, but that didn't help).
Hello Gary,
Just checking in, did you still require assistance on this matter?
Sincerely,AndrewAssociate DeveloperInfragistics Inc.www.infragistics.com/support
Thank you for the updated project. Unfortunately, I am still unable to reproduce this threading issue you are seeing. I have been digging into the source code of the XamDataChart to find the OnTemplateProvided() methods, as you requested. Being that this issue seems to be spawning from a SetBinding operation within the OnTemplateProvided methods, I will focus on them.
It appears that the SeriesViewerView.OnTemplateProvided is retrieving the SeriesViewer for the XamDataChart and applying a few different bindings for the crosshair layers, tooltip layers, the outer border of the chart, and the zoom bar if it is enabled. Most of these bindings are for the Style property, but the outer border has bindings to its BorderBrush, BorderThickness, and Background properties as well. All of the paths for these bindings being set are retrieved from the SeriesViewer.
The XamDataChartView.OnTemplateProvided is an override of the SeriesViewerView one. The differences are that the bindings are set only on the zoom bar with respect to its Visibility property. There is also a binding to the presenter of the background of the plot area for its Content property, but I don't believe this is what is causing the issue.
Are you using any sort of styling for crosshair layers, tooltip layers, or zoom bars in the chart that is crashing in your application?
Please let me know if you have any other questions or concerns on this matter.
One the same note, we don't really know if the EnsureApplicationResources() method is the correct way to get WPF initialized from within a WinForm application and I am not sure if these have to be loaded once or per thread .
Thanks, I have attached a quickly updated file set - this includes the EnureApplicationResources() method, but some DLL inclusions are probably needed for this to compile) - essentially, this loads XAML needed for customizing a XamGrid and that requires a stock Infragistics generic XML file.
We are not able to produce this on demand, so any insight you can give to what these methods are doing might help:
at Infragistics.Controls.SeriesViewerView.OnTemplateProvided() at Infragistics.Controls.Charts.XamDataChartView.OnTemplateProvided()