On occasion, when I set the theme in code behind, I get an exception with the message "The calling thread cannot access this object because a different thread owns it."
Here is the call stack:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Threading.DispatcherObject.VerifyAccess()
at System.Windows.Style.CheckTargetType(Object element)
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 Infragistics.Windows.DataPresenter.GroupByAreaFieldLabel.SetStyle(Style defaultStyle)
at Infragistics.Windows.DataPresenter.GroupByArea.CreateGroupByAreaFieldLabelFromField(Field field, Style defaultStyle, Boolean forGroupedFieldsArea)
at Infragistics.Windows.DataPresenter.GroupByArea.RefreshAvailableFieldLabels(FieldLayout fieldLayout, GroupByAreaFieldLabelCollection availableFieldLabels, Boolean notifyCollectionChanged)
at Infragistics.Windows.DataPresenter.GroupByArea.OnThemeChanged(Object sender, RoutedPropertyChangedEventArgs`1 e)
at System.Windows.RoutedPropertyChangedEventArgs`1.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at Infragistics.Windows.DataPresenter.DataPresenterBase.RaiseEventHelper(RoutedEventArgs args)
at Infragistics.Windows.DataPresenter.DataPresenterBase.OnThemeChanged(String previousValue, String currentValue)
at Infragistics.Windows.DataPresenter.DataPresenterBase.OnThemeChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
at System.Windows.PropertyChangedCallback.Invoke(DependencyObject d, DependencyPropertyChangedEventArgs e)
at Infragistics.Windows.DataPresenter.DataPresenterBase.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at Infragistics.Windows.DataPresenter.XamDataGrid.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at Infragistics.Windows.DataPresenter.DataPresenterBase.set_Theme(String value)
It does not happen every time I set the theme, but since it’s deep inside of the data grid’s code, I can’t figure out the cause or solution.
Any ideas?
Thanks
Dan
HI,
I am just following up on this thread.
Please let me know if you need further assistance.
Sincerely,
Mattt DSE
Can you provide a small isolated sample that replicates this issue?
Sincerely, Matt Developer Support Engineer
Matt,
I should have mentioned that the method I provided is part of a class that inherits from XamDataGrid. I’m already calling the Theme set property within an action that is dispatched to the grid’s thread. I’ll add a CheckAccess, however, this will only tell me if I can call the action directly, or if I need to call it via a dispatcher. Since the exception is within the grid’s dispatcher already, I don’t see where it will make any difference.
Try using the DependencyObjects.CheckAccess method. This method will determine whether a thread is the same thread that created the DependencyObject.
Here is a MSDN Link:
http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.checkaccess(v=vs.95).aspx
Sincerely, Matt DSE
Version 10.3.20103.1003
The original problem was when setting the DataSource binding it was throwing an exception. I tracked this down to only happening when the Theme was set, so I null out the theme, set the DataSource, then restore the Theme. It fixed the exception being thrown when setting the DataSource, but just moved it to the setting of the Theme. A few things to note: It does not happen all of the time and I can't predict when it will happen. It happens when opening several windows that contain grids. Our application is heavily threaded, so we use dispatchers to ensure processing happens in the proper threads. Here is the code:
static object m_objMutex = new object();
public void SetDataSource(object newItemSourceBinding)
{
if (newItemSourceBinding != null)
// Set the data source binding
Action action = new Action(() =>
lock (m_objMutex)
// If necessary, Save off then clear out the current theme
// Note: There are issues with setting the item source binding while the theme is overridden. It will
// sometimes result in a cross thread exception. By nulling the theme, we can avoid this at
// bind time.
string strTheme = null;
if (string.IsNullOrEmpty(Theme) == false)
try
strTheme = Theme;
Theme = null;
}
catch (Exception ex)
RCS.Logging.Logger.LogException(ex, true);
// If type of List Source, as it for the list
IListSource iListSource = newItemSourceBinding as IListSource;
IList iList = null;
if (null != iListSource)
iList = iListSource.GetList();
else
iList = newItemSourceBinding as IList;
// Set the item source's binding
Binding binding = new Binding();
binding.Source = iList;
SetBinding(DataSourceProperty, binding);
// If necessary, retore the theme
if (string.IsNullOrEmpty(strTheme) == false)
// Restore the theme
Theme = strTheme;
});
this.Dispatcher.Invoke(DispatcherPriority.Background, action);