A day with .Net

My day to day experince in .net

INotifyPropertyChanged Cross thread change notification issue solved.

Posted by vivekcek on May 7, 2013

I hope you are here beacause, your class implemented INotifyPropertyChanged and a list of the same is bind to a gridview or something.

But you tried to change the objects in that binded list in another thred, i mean out side the UI thread.

So what happend?, when the object is manipulted in another thread, change notification are fired and the other thred tried to update the gridvivew. So how can you slove this.

1. First of all i will introduce a class named ‘EntityBase’ which implement the’INotifyPropertyChanged’.

 public abstract class EntityBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual bool UpdateField<T>(ref T field, T value, string
        propertyName)
        {
            if (EqualityComparer<T>.Default.Equals(field, value)) return
            false; 
            field = value;
            if (!string.IsNullOrEmpty(propertyName))
                OnPropertyChanged(propertyName);
            return true;
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

2. Your class say ‘Contact’ should be derived from EntityBase as given below.
Note the change in Set{}.

 public class Contact : EntityBase
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set { UpdateField(ref _name, value, "Name"); }
        }
           

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(object sender, string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

3. Now we will create a thread safe generic class ThreadedBindingList by extending BindingList

 public class ThreadedBindingList<T> : BindingList<T>
    {
        SynchronizationContext ctx = SynchronizationContext.Current;
        protected override void OnAddingNew(AddingNewEventArgs e)
        {
            
            if (ctx == null)
            { BaseAddingNew(e); }
            else
            { ctx.Send(delegate { BaseAddingNew(e); }, null); }
        }

        void BaseAddingNew(AddingNewEventArgs e)
        { base.OnAddingNew(e); }

        protected override void OnListChanged(ListChangedEventArgs e)
        {
            
            if (ctx == null)
            { BaseListChanged(e); }
            else
            { ctx.Send(delegate { BaseListChanged(e); }, null); }
        }

        void BaseListChanged(ListChangedEventArgs e)
        { base.OnListChanged(e); }
    }

4. Now your form class will be like this.

using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using DevExpress.XtraGrid.Views.Grid;
using System.Threading;
namespace WinFormInotyFy
{
    public partial class Form1 : Form
    {
        
        ThreadedBindingList<Contact> contacts = new ThreadedBindingList<Contact>();
        public Form1()
        {
            InitializeComponent();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            
            contacts.Add(new Contact() { Name="vivek" });
            contacts.Add(new Contact() { Name = "vivek" });
            contacts.Add(new Contact() { Name = "vivek" });
            contacts.Add(new Contact() { Name = "vivek" });
            contacts.Add(new Contact() { Name = "vivek" });
            gridControl1.DataSource = contacts;
        }

        private void button1_Click(object sender, EventArgs e)
        {
                       
            Parallel.ForEach(contacts, c => { c.Name += 1; c.IsProgress = false; });
          
        }

     
    }

    
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s