Click here to Skip to main content
15,886,689 members
Articles / Programming Languages / C#

Multithreading Demystified

Rate me:
Please Sign up or sign in to vote.
4.77/5 (45 votes)
25 Jan 2013CPOL22 min read 75.3K   2.3K   170  
Multi-threading in .NET - A walkthrough.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;

namespace Demo.Threading.Performance
{
    class Program
    {
        static ManualResetEvent mset = new ManualResetEvent(false);
        //static string Path = @"E:\LargeFiles";
        static string Path = @"E:\Snapshots";
        static DirectoryInfo di = new DirectoryInfo(Path);
        static int workerThread;
        static int ioThread;
        delegate void dThreadPool(FileInfo fi);

        static void Main(string[] args)
        {            
            ThreadPerformance tp = new ThreadPerformance(mset) 
            { DestinationLocation = @"E:\NewCopy\", FileCount = di.GetFiles().ToList().Count };
            
            ThreadPool.SetMinThreads(di.GetFiles().ToList().Count, 0);

            ThreadPool.GetAvailableThreads(out workerThread, out ioThread);
            Console.WriteLine("WorkerThreads: {0}, IO Threads {1}", workerThread, ioThread);

            Console.WriteLine("Type 1 -- Copy files using worker threads");
            Console.WriteLine("Type 2 -- Read files using worker threads");
            Console.WriteLine("Type 3 -- Read files using IO threads");

            bool exitApplication=false;
            while (!exitApplication)
            {
                int input = Convert.ToInt16(Console.ReadLine());
                
                switch (input)
                {
                    case 1:
                        Console.WriteLine("Copying files using worker threads..{0}", DateTime.Now);
                        DoWork(new dThreadPool(tp.CopyWithWorkerThread));
                        break;
                    case 2:
                        Console.WriteLine("Reading files using worker threads..{0}", DateTime.Now);
                        DoWork(new dThreadPool(tp.ReadWithWorkerThread));
                        break;
                    case 3:
                        Console.WriteLine("Reading files using IO threads..{0}", DateTime.Now);
                        DoWork(new dThreadPool(tp.ReadWithIOThread));
                        break;
                    case 4:
                        Console.WriteLine("Exit Application");
                        exitApplication = true;
                        break;
                    default:
                        Console.WriteLine("Invalid Input");
                        break;
                }
            }
        }

        static void DoWork(dThreadPool del)
        {
            foreach (FileInfo file in di.GetFiles())
            {                
                del.Invoke(file);
                ThreadPool.GetAvailableThreads(out workerThread, out ioThread);
                Console.WriteLine("WorkerThreads: {0}, IO Threads {1}", workerThread, ioThread);
            }
            mset.WaitOne();
            Console.WriteLine("Operation Complete {0}", DateTime.Now);
            mset.Reset();
            ThreadPool.GetAvailableThreads(out workerThread, out ioThread);
            Console.WriteLine("Final Count - WorkerThreads: {0}, IO Threads {1}", workerThread, ioThread);
        }
    }

    public class ThreadPerformance
    {
        private ManualResetEvent mset;
        private FileStream fs;
        public ThreadPerformance(ManualResetEvent Mset)
        {
            mset = Mset;
        }

        public string DestinationLocation { get; set; }
        public int FileCount { get; set; }

        int count;

        public void CopyWithWorkerThread(FileInfo File)
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                try
                {
                    Console.WriteLine("Copying file - {0}", File.Name);
                    File.CopyTo(DestinationLocation + File.Name, true);
                    count += 1;

                    if (count == FileCount)
                    {
                        count = 0;
                        mset.Set();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception :{0}", ex.Message);
                    mset.Set();
                }
                finally
                {
                    
                }  
            });            
        }

        public void ReadWithWorkerThread(FileInfo File)
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                try
                {
                    Console.WriteLine("Reading file - {0}", File.Name);
                    fs = new FileStream(File.FullName, FileMode.OpenOrCreate);
                    using (fs)
                    {
                        int length = (int)fs.Length;
                        byte[] buffer = new byte[length];
                        fs.Read(buffer, 0, length);
                        count += 1;
                        if (count == FileCount)
                        {
                            count = 0;
                            mset.Set();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception :{0}", ex.Message);
                    mset.Set();
                }
                finally
                {}
            });
        }

        public void ReadWithIOThread(FileInfo File)
        {
            try
            {
                Console.WriteLine("Reading file - {0}", File.Name);
                fs = new FileStream(File.FullName, FileMode.OpenOrCreate);
                int length = (int)fs.Length;
                byte[] buffer = new byte[length];
                fs.BeginRead(buffer, 0, length, CallBack, null); 
            }
            catch (Exception ex)
            {                
                Console.WriteLine("Exception :{0}", ex.Message);
            }
            finally
            { }                              
        }

        private void CallBack(IAsyncResult ar)
        {
            using (fs)
            {
                try
                {
                    fs.EndRead(ar);
                    Console.WriteLine("Completed Operation for {0}", fs.Name);
                    count += 1;
                    if (count == FileCount)
                    {
                        count = 0;
                        mset.Set();
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception : {0}", fs.Name);
                }

            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
I am a Senior Software Developer / Technical Consultant in a leading software company.

Comments and Discussions