C#, MultiThreading

Producer Consumer Problem using locks in C#.Net

Problem Statement

The Producer Consumer problem is a classical Multithreaded problem which involves synchronization among multiple threads which are producing/consuming items from a resource at different speeds.

There are different ways to solve this problem in C#. I would be using the Monitor class for locking and its Wait/Pulse methods for signalling.

The client of the ProducerConsumer Class could use the old Threading API (Thread class) to spin off threads which try to consume/produce items or use TPL to use threads from the ThreadPool.

Code

using System.Collections.Generic;
using System.Linq;
using System.Threading;
 
namespace MultiThreading
{
    internal class ProducerConsumerProblem
    {
        private readonly object _lock = new object();
        private readonly Queue<int> queue = new Queue<int>();
 
 
        public void Produce(int input)
        {
            lock (_lock)
            {
                queue.Enqueue(input);
                Monitor.Pulse(_lock);
            }
        }
 
        public int Consume()
        {
            lock (_lock)
            {
                while (!queue.Any())
                {
                    Monitor.Wait(_lock);
                }
 
                return queue.Dequeue();
            }
        }
    }
}

Test

 [TestMethod]
       public void PoducerConsumerProblem_Should_Succeed()
       {
           var producerConsumerProblem = new ProducerConsumerProblem();
 
           Thread.CurrentThread.Name = "Main Consumer Thread";
           var t1=new Thread(
             () => producerConsumerProblem.Produce(1)) {Name = "Producer Thread"};
           t1.Start();
 
           producerConsumerProblem.Consume();
         
 
           var t2 =new Thread(
               () =>
               {
                   for (int i = 0; i < 10; i++)
                   {
                       producerConsumerProblem.Produce(i);
                   }
                   
               }
               ) {Name = "Producer Thread 2"};
 
           t2.Start();
       }

Final Words

.NET Framework 4.5 has a Concurrent collection called BlockingCollection which solves the same Producer-Consumer problem. In case you are using a former version of the framework, using Monitor is the simplest way to solve the problem. You can also use Semaphores to restrict Threads to a certain number (maybe depending on the cores of your system).

Standard
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&lt;T&gt; : ObservableCollection&lt;T&gt;
    {
        private SynchronizationContext synchronizationContext = SynchronizationContext.Current;

        public AsyncObservableCollection()
        {
        }

        public AsyncObservableCollection(IEnumerable&lt;T&gt; 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);
        }
    }
Standard
C#, MultiThreading

Ways to implement MultiThreading in C#

I have been using Threads in C# from quite a while now and it would not be wrong to say that I always mix up APIs in C# which allow to create threads/ use thread pools for that matter.

There are literally many ways to go about Threading in C# and I finally decided to jot down all ways I know so that I don’t end up mixing them again.

Here are the ways with code samples:

         1
         // Passing the method name to be executed in the ctor directly without using ThreadStart delegate
         var thread1 = new Thread(DoSomeWork);
         thread1.Start();
 
         2
         // Passing the ThreadStart delegate  which points to a method to be executed
         var threadStart = new ThreadStart(DoSomeWork);
         var thread2 = new Thread(threadStart);
         thread2.Start();
 
          3
         // Passing the ParametrizedThreadStart delegate  which points to the method to be executed
         var parametrizedThreadStart = new ParameterizedThreadStart(DoSomeWorkWithParameter);
         var thread3 = new Thread(parametrizedThreadStart);
         thread3.Start(2);
 
         4
         // Passing a Lambda expression in the Thread class constructor and subsequently calling the Start method
         var thread4 = new Thread(() =>
         {
             int x = 5;
             for (int i = 0; i < x; i++)
             {
                 Console.WriteLine(i);
             }
         });
 
         thread4.Start();
 
         5
         // Leveraging ThreadPools, call ThreadPool.QueueUserWorkItem passing in the method name to be executed
         ThreadPool.QueueUserWorkItem(DoSomeWorkWithParameter);
         ThreadPool.QueueUserWorkItem(DoSomeWorkWithParameter, 4);
 
            6
         // Using TPL (Task Parallel Library). Create a Task<T>, where T is the return type of the method to be executed.
         Task<string> task = Task.Factory.StartNew<string>(DoSomeStringWork);
         var result = task.Result;
 
           7
        // Instantiating Task class directly
            var task = new Task(
                () =>
                {
                    Console.WriteLine("Worker thread!");
                    Thread.Sleep(1000);
                });
 
            task.Start();

 8
// Using Asynchronous Delegates, also known as the APM pattern 
Func<stringstring> work = DoSomeStringWork;
IAsyncResult res = work.BeginInvoke(“Hello”nullnull);
string result1 = work.EndInvoke(res);
}

Utility Methods:

static void DoSomeWorkWithParameter(object a)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(“Do some work invoked, Thread Id:{0}, i);
}

}

static void DoSomeWork()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(“Do some work invoked, Thread Id:{0}, i);
}

}

static string DoSomeStringWork()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(“Do some work invoked, Thread Id:{0}, i);
}
return “a”;
}

static string DoSomeStringWork(string a)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(“Do some work invoked, Thread Id:{0}, i);
}
return “a”;
}

Standard