C#, MultiThreading, wpf

Modifying ObservableCollection from worker threads in WPF

If you have worked with WPF and used DataBinding you would know that if you want to update the UI when an object changes other than from the binding, you have to implement INotifyPropertyChanged Interface (Or use Dependency properties) and if you are working with a collection, then the best bet is to use an Observable collection which makes updates to the UI when the underlying collection is modified (Add, Delete etc).

PROBLEM

All works well until you are working with Threads and your worker threads try to modify the ObservableCollection.

You would see an exception like this


System.NotSupportedException : This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

SOLUTION

If you are using WPF 4.5  then all you have to do is this:

  1. Create the ObservableCollection in the main thread (usually done in the ViewModel)
  2. Use BindingOperations.EnableCollectionSynchronization(YourObservableCollection, A class level lock)
    BindingOperations.EnableCollectionSynchronization(EnvironmentErrors, _lock);

That is it, now you can update the ObservableCollection from worker threads and see the UI being updated at the same time.

If you aren’t using WPF 4.5 then you can use this AsynchronousObservableCollection class to update the collection from non-ui threads.

 public class AsyncObservableCollection<T> : ObservableCollection<T>
    {
        private SynchronizationContext synchronizationContext = SynchronizationContext.Current;

        public AsyncObservableCollection()
        {
        }

        public AsyncObservableCollection(IEnumerable<T> list)
            : base(list)
        {
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (SynchronizationContext.Current == synchronizationContext)
            {
                RaiseCollectionChanged(e);
            }
            else
            {
                synchronizationContext.Send(RaiseCollectionChanged, e);
            }
        }

        private void RaiseCollectionChanged(object param)
        {
            base.OnCollectionChanged((NotifyCollectionChangedEventArgs) param);
        }

        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (SynchronizationContext.Current == synchronizationContext)
            {
                RaisePropertyChanged(e);
            }
            else
            {
                synchronizationContext.Send(RaisePropertyChanged, e);
            }
        }

        private void RaisePropertyChanged(object param)
        {
            base.OnPropertyChanged((PropertyChangedEventArgs) param);
        }
    }
Advertisements
Standard
Design Patterns

Singleton Design Pattern C#

The most simplest of the Design Patterns to implement, but one has to keep in check few corner cases to get it right.

Let us see a naive implementation first which works well (at least it will look like it works well :-P) but then it wouldn’t work in a multi threaded environment.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace SingletonPatternConsoleApplication
{
 
    /// <summary>
    /// Singleton class, only one instance would be created at any time.
    /// </summary>
    class Singleton
    {
        private static Singleton singleton;
 
        /// <summary>
        /// Private constructor in order to force singleton
        /// </summary>
        private Singleton()
        {
 
        }
 
        public static Singleton CreateSingleton()
        {
            //This code isn't Thread Safe and can lead to multiple instances of Singleton Class.
            //If two threads come to this point at the same instance when singleton is still null, then there's a chance that both would create a new instance.
            if (singleton == null)
            {
                singleton = new Singleton();
                Console.WriteLine("Instance created!");
            }
            return singleton;
 
        }
 
 
    }
}

Let us see the thread safe version of the Singleton Pattern:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace SingletonPatternConsoleApplication
{
 
    /// <summary>
    /// Singleton class, only one instance would be created at any time.
    /// </summary>
    class SingletonThreadSafe
    {
        private static readonly object _lock = new object();
        private static SingletonThreadSafe singleton;
 
        /// <summary>
        /// Private constructor in order to force singleton
        /// </summary>
        private SingletonThreadSafe(){ }
 
        public static SingletonThreadSafe CreateSingleton()
        {
            lock (_lock)
            {
 
                if (singleton == null)
                {
                    singleton = new SingletonThreadSafe();
                }
                return singleton;
            }
        }
    }
}
Standard