Friday, May 14, 2010

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

Hi,

Today I faced an issue with my custom control which has my own DictionaryList with custom CustomKeyValuePair class as Value of dictionary list. Key is a string type, so nothing problem on it. I used this dictionary list for storing resources to provide different skin support in my control template. Note the point, my CustomKeyValuePair class inherited from DependencyObject. After implementing my control with effective skin mechanism, I tried to host my control in multi threaded WPF application. But unfortunately I got this error message {"The calling thread cannot access this object because a different thread owns it."} since calling thread uses my dictionary list Value(CustomKeyValuePair). As I said, this class inherited from DependencyObject, so WPF won't allow you to access dependency property in multi thread application.

Initially I tried to solve this issue with value cloning logic. But no use. Finally tried with INotifyPropertyChanged class. Yes, I just removed base class DependencyObject from CustomKeyValuePair class and implemented INotifyPropertyChanged interface with Value property notification when its value getting changed. Now my controls works in multithread WPF application perfectly J


public class CustomKeyValuePair : INotifyPropertyChanged //DependencyObject
{
//public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(PairKeyValue), new UIPropertyMetadata(null));

//public object Value
//{
// get
// {
// return (object)GetValue(ValueProperty);
// }
// set
// {
// SetValue(ValueProperty, value);
// }
//}

// Solution for "The calling thread cannot access this object because a different thread owns it."

object _value;

/// <summary>
/// Gets or sets the value in key-value pair.
/// </summary>
public object Value
{
get
{
return _value;
}
set
{
_value=value;
OnPropertyChanged("Value");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}

Enjoy J

-Venugopal.