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
Hello Gary,
I apologize for the delay in my response.
That is interesting that setting the CrosshairLineStyle, CrosshairToolTipStyle, and ToolTipStyle to a new, empty Style object seems to be preventing this issue. After some investigation on this, I had taken a look at the default style file for XamDataChart with regards to the default styles for these three issues, and each of them have a SafeSetterCollection in common, which is referenced in the stack trace of the exception you are referring to.
Regarding whether or not there is any development work happening regarding a bug fix for this, I am not aware of any at the moment, as I haven't found anything in our internal tracking system, but there wasn't much to go on up until this point, as this narrows things down to those styles that are being applied to the XamDataChart.
I will be investigating and discussing this issue with our development teams with regards to these styles and the operations that are happening within the SafeSetters to try to get a better idea of what is happening here. I hope to have more information for you on this matter soon.
Please let me know if you have any other questions or concerns on this matter.
Sincerely,AndrewAssociate Developer
Hi Andrew, we still don't have a good mechanism to reproduce this problem, however, based on a Google search for the error stack trace specifics, this article came up:
http://ko.infragistics.com/community/forums/t/51368.aspx
Based on the information posted, we extended the XamDataChart class like this:
public class XamDataChartEx : XamDataChart { public XamDataChartEx() : base() { this.CrosshairLineStyle = new Style(); this.CrosshairTooltipStyle = new Style(); this.ToolTipStyle = new Style(); this.Brushes = new BrushCollection() { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Blue), new SolidColorBrush(Colors.Black), new SolidColorBrush(Colors.Orange) }; this.MarkerBrushes = new BrushCollection() { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Blue), new SolidColorBrush(Colors.Black), new SolidColorBrush(Colors.Orange) }; this.Outlines = new BrushCollection() { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Blue), new SolidColorBrush(Colors.Black), new SolidColorBrush(Colors.Orange) }; this.MarkerOutlines = new BrushCollection() { new SolidColorBrush(Colors.Red), new SolidColorBrush(Colors.Blue), new SolidColorBrush(Colors.Black), new SolidColorBrush(Colors.Orange) }; } }
and switched out our XamDataChart references with this extended version, and that seems to have prevented this error from happening over the past few weeks. The article implies that the XamDataChart must not be multi-thread safe in some way, possibly from trying to use shared/default resources that get created in a thread other than the thread the chart is created in. Are you aware of any bug fixes or other work for resolving these issues? We seemed to have experienced similar problems when upgrading to the latest version and trying to use the new WPF spinner control - we ended up falling back to a previous version due to stability concerns.
For a previous work around to get a feature on the XamGrid, we created an extended version of that and had to pre-load XamGrid version of "generic.shared.xaml" from the Infragistics install directory "C:\Program Files (x86)\Infragistics\2015.1\WPF\DefaultStyles\XamGrid". This file's content does not match with the corresponding one in the XamDataChart and I am wondering if this was/is creating some kind of initialization conflict between these two controls/files? We are not pre-loading the XamDataChart version of this file. The code for pre-loading is executed in Program.cs before any windows are opened and looks like this (the main application is a WinForm that interops with WPF):
public static vEnsureApplicationResources() { if (System.Windows.Application.Current == null) { // create the Application object System.Windows.Application app = new System.Windows.Application(); app.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; // merge in application resources System.Windows.Application.Current.Resources.MergedDictionaries.Add( System.Windows.Application.LoadComponent( new Uri("/Library;component/UI/WPF/Infragistics/generic.shared.xaml", UriKind.RelativeOrAbsolute)) as System.Windows.ResourceDictionary); // merge in application resources System.Windows.Application.Current.Resources.MergedDictionaries.Add( System.Windows.Application.LoadComponent( new Uri("/Library;component/UI/WPF/Infragistics/XamGridCustomizations.xaml", UriKind.RelativeOrAbsolute)) as System.Windows.ResourceDictionary); } }
Any thoughts on this would be helpful.
Thanks!
Thank you for your response. I will continue to monitor this forum thread while I await your next update with your working example.
Sincerely,AndrewAssociate DeveloperInfragistics Inc.www.infragistics.com/support
Yes, this is a difficult one to figure out. Our application is huge (and proprietary), so I can't send it as is. In the past with these issues, I have cut down the application to just the offending code base to provide an example app, but with this issue, I don't have a predictable way to reproduce it. That being said, I will try to reduce code down to a working example that preserves the flow of code execution, but it will take some time.
E.
I am not sure this issue can be avoided by pre-initializing objects, as I believe what is causing it is that somewhere in your application a static resource is being created that does not get destroyed when a window is closed. Since these windows are in threads of their own, then when another window opens up, this static resource is still owned by the old thread, and hence, you see the exception that you are seeing. I also have my doubts that this is coming from a re-boot after a Windows update, but I cannot be entirely sure on that.
I am curious if there are any styles or themes that you are applying to the XamDataChart itself that you could possibly provide. If there are, would it be possible for you to modify the application that I had sent to include these applications of these styles? Also, how many series do you have in the problematic chart? What kind of axes are you using? Any details on your XamDataChart that you can provide to help me to reproduce this issue are welcomed, as I can't really be too sure how to proceed with this unless able to reproduce this crash that you and your users are seeing.