1
Vote

The calling thread cannot access this object because a different thread owns it.

description

I have an application where a second window is created in a separate thread (say thread2), from the main UI (say thread1). Now in, thread2 itself, within a method, I create a TransitionElement control and make it the child of the thread2 Window. And then create a Canvas that is set to the Content of the TransitionElement.Content. This is where my application throws the thread access error. Following is the StackTrace;

 

The calling thread cannot access this object because a different thread owns it.
 
at System.Windows.Threading.DispatcherObject.VerifyAccess()
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 Transitionals.Transitions.StoryboardTransition.BeginTransition(TransitionElement transitionElement, ContentPresenter oldContent, ContentPresenter newContent) in C:\Users\Manish\Documents\Visual Studio 2010\Projects\Digital Signage\Transitionals\Transitions\StoryboardTransition.cs:line 84
at Transitionals.Controls.TransitionElement.BeginTransition() in C:\Users\Manish\Documents\Visual Studio 2010\Projects\Digital Signage\Transitionals\Controls\TransitionElement.cs:line 488
at Transitionals.Controls.TransitionElement.OnContentChanged(Object element, DependencyPropertyChangedEventArgs e) in C:\Users\Manish\Documents\Visual Studio 2010\Projects\Digital Signage\Transitionals\Controls\TransitionElement.cs:line 206
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 Transitionals.Controls.TransitionElement.set_Content(Object value) in C:\Users\Manish\Documents\Visual Studio 2010\Projects\Digital Signage\Transitionals\Controls\TransitionElement.cs:line 168

at Trevidea.ZoneLayout.Zone.mCompere_RequestHosting(IZone zone, OrderRow orderRow) in C:\Users\Manish\Documents\Visual Studio 2010\Projects\Digital Signage\ZoneLayout\Zone.cs:line 122

 
The error actually originates from the Transitionals.Transitions.StoryboardTransition.BeginTransition() method, when "newContent.Style = NewContentStyle;" is called. The newContent here is my Canavs that I created in Thread2. I have compared the Dispatcher.Thread.ManagedThreadId for newContent and NewContentStyle, which turn out to be different. I would also like to add that I am setting a Transition on the TransitionElement, but of course in the same thread (thread2) as;
     Transitionals.Controls.TransitionElement transitionElement =
            new Transitionals.Controls.TransitionElement()
            {
                Transition = new Transitionals.Transitions.CheckerboardTransition()
            };
If I do not apply the above Transition then everything works fine.
 
Now I am just wondering that if the ManagedThreadId of the Canvas and the TransitionElement (created in Thread2) are same, then why is the ManagedThreadId of NewContentStyle different.
I'll appreciate a quick reply. We are running a Sprint.
 
Thanks and Regards
Manish

comments

vermamanish wrote Feb 21, 2011 at 9:00 AM

Observation#1: inside the Transitionals.Transitions.CheckerboardTransition class, instead of initializing the instance of CheckerboardTransitionFrameworkElement as static, if I initialize it within the constructor of the CheckerboardTransition class, it works fine.

public class CheckerboardTransition : StoryboardTransition
{
    //static private CheckerboardTransitionFrameworkElement frameworkElement = new CheckerboardTransitionFrameworkElement();

    public CheckerboardTransition()
    {
        CheckerboardTransitionFrameworkElement frameworkElement = new CheckerboardTransitionFrameworkElement();
        this.NewContentStyle = (Style)frameworkElement.FindResource("CheckerboardTransitionNewContentStyle");
        this.NewContentStoryboard = (Storyboard)frameworkElement.FindResource("CheckerboardTransitionNewContentStoryboard");
    }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.NotSupportedException.#ctor(System.String)")]
    protected override void OnDurationChanged(Duration oldDuration, Duration newDuration)
    {
        throw new System.NotSupportedException("CTP1 does not support changing the duration of this transition");
    }
}

vermamanish wrote Feb 21, 2011 at 9:18 AM

Observation#2: if I use a Transition that has not been used anywhere in the project before, then it works fine.

Obviously, the reason is that if a transition is used elsewhere before (in my case I had used CheckerboardTransition in the application, before) then the CheckerboardTransitionFrameworkElement is initialized in that thread itself. And when I try to use the same transition in another thread, the instance of CheckerboardTransitionFrameworkElement (and hence its style) become inaccessible.

Obviously there must be some good reason to keep the instance of the CheckerboardTransitionFrameworkElement static. My question is, if there could be a workaround with this problem that, I understand, cannot be singular to my case.

Regards
Manish

wrote Feb 14, 2013 at 7:30 PM