Click here to Skip to main content
15,888,803 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I came across with situation where I have to create multiple thread in windows service.Here is my code.Here I have created 2 thread.

I want create a one notepad file.Want to print number from 0 to 2999 with 2 thread.It suppose to print some number from thread 1 and that some number from thread2 and again from thread1 like this.I am not getting the same output. I am sharing my code and output.


Service code :

public partial class FileMultiTasking : ServiceBase
    {
        static System.Timers.Timer timer;
        public static string apppath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
        public static string errormsg;

        PrintDetails thr1 = new PrintDetails();
        PrintDetails thr2 = new PrintDetails();

        Thread thread1, thread2;

        public FileMultiTasking()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            timer = new System.Timers.Timer();

            timer.Enabled = true;
            timer.Start();

            timer.Interval = 50000;

            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
           
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            timer.Enabled = true;

            CreateThread();
        }

        private void CreateThread()
        {
            try
            {
                timer.Enabled = false;

         
                 thread1 = new Thread(() => thr1.TextLog("First Thread : Service Started "));
                 thread2 = new Thread(() => thr2.TextLog("Seconf Thread : Service Started"));


                thread1.Name = "Thread 1";
                thread2.Name = "Thread 2";

                thread1.Start();
                thread2.Start();

                timer.Enabled = true;
            }
            catch (Exception ex)
            {
                timer.Enabled = true;
            }
        }


        protected override void OnStop()
        {
            timer.Enabled = false;

            errormsg = "Service Stopped ...............";
                                  
        }
    }



class code : 
<pre> class PrintDetails
    {
        public string apppath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();

        public void TextLog(string msg)
        {
            try
            {
                StreamWriter sw;
                FileInfo f;
                Thread thr = Thread.CurrentThread;
                int j = 0;

             //   string s = apppath + thr.Name + " PrintDetails " + DateTime.Today.ToString("dd-MM-yyyy") + ".txt";

                string s = apppath +  " PrintDetails " + DateTime.Today.ToString("dd-MM-yyyy") + ".txt";

                f = new FileInfo(s);
                if (f.Exists)
                {
                    sw = f.AppendText();
                }
                else
                {
                    sw = f.CreateText();
                    sw.WriteLine();
                }
                sw.WriteLine("-----------------------------------------------------------------");
                sw.WriteLine(msg + "    " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff"));

                if (msg == "Service Stopped ...............")
                {

                }
                else
                {
                    for (int i = 0; i < 3000; i++)
                    {

                        Thread thr2 = Thread.CurrentThread;

                        if (thr2.Name == "Thread 1")
                        {
                            sw.WriteLine(thr2.Name + " : " + i + "    " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff"));
                        }
                        else
                        {
                            sw.WriteLine(thr2.Name + " ::: " + i + "    " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff"));
                        }

                        Console.WriteLine(j);

                        if (j == 0)
                        {
                            j = j + 1;
                            sw.WriteLine("Thread will sleep now -----------------------------------------------------------------");
                            Thread.Sleep(1000);
                        }
                    }
                  
                }
                

                sw.Close();
            }
            catch (Exception e)
            {
                msg = e.Message;
                TextLog(msg);
            }
        }
    }



Output :

First Thread : Service Started     2018.06.13 12:22:52:8443
Thread 1 : 0    2018.06.13 12:22:52:8443
Thread will sleep now -----------------------------------------------------------------
Thread 1 : 1    2018.06.13 12:22:53:8600
Thread 1 : 2    2018.06.13 12:22:53:8600
Thread 1 : 3    2018.06.13 12:22:53:8600
Thread 1 : 4    2018.06.13 12:22:53:8600
Thread 1 : 5    2018.06.13 12:22:53:8600
Thread 1 : 6    2018.06.13 12:22:53:8600
Thread 1 : 7    2018.06.13 12:22:53:8600
Thread 1 : 8    2018.06.13 12:22:53:8600
Thread 1 : 9    2018.06.13 12:22:53:8600
Thread 1 : 10    2018.06.13 12:22:53:8600
like 2999

The process cannot access the file 'C:\Program Files (x86)\PrintDetails 13-06-2018.txt' because it is being used by another process.    2018.06.13 12:22:53:8912

Thread 2 ::: 0    2018.06.13 12:22:53:8912
Thread will sleep now -----------------------------------------------------------------
Thread 2 ::: 1    2018.06.13 12:22:54:9011
Thread 2 ::: 2    2018.06.13 12:22:54:9011
Thread 2 ::: 3    2018.06.13 12:22:54:9011
Thread 2 ::: 4    2018.06.13 12:22:54:9011
Thread 2 ::: 5    2018.06.13 12:22:54:9011
Thread 2 ::: 6    2018.06.13 12:22:54:9011
Thread 2 ::: 7    2018.06.13 12:22:54:9011
Thread 2 ::: 8    2018.06.13 12:22:54:9011
Thread 2 ::: 9    2018.06.13 12:22:54:9011
Thread 2 ::: 10    2018.06.13 12:22:54:9011
till 2999
//

Why this so?What change shall I do to get output as wanted.


What I have tried:

Service code : 

<pre>public partial class FileMultiTasking : ServiceBase
    {
        static System.Timers.Timer timer;
        public static string apppath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
        public static string errormsg;

        PrintDetails thr1 = new PrintDetails();
        PrintDetails thr2 = new PrintDetails();

        Thread thread1, thread2;

        public FileMultiTasking()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            timer = new System.Timers.Timer();

            timer.Enabled = true;
            timer.Start();

            timer.Interval = 50000;

            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
           
        }

        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            timer.Enabled = true;

            CreateThread();
        }

        private void CreateThread()
        {
            try
            {
                timer.Enabled = false;

         
                 thread1 = new Thread(() => thr1.TextLog("First Thread : Service Started "));
                 thread2 = new Thread(() => thr2.TextLog("Seconf Thread : Service Started"));


                thread1.Name = "Thread 1";
                thread2.Name = "Thread 2";

                thread1.Start();
                thread2.Start();

                timer.Enabled = true;
            }
            catch (Exception ex)
            {
                timer.Enabled = true;
            }
        }


        protected override void OnStop()
        {
            timer.Enabled = false;

            errormsg = "Service Stopped ...............";
                                  
        }
    }



class code : 
<pre> class PrintDetails
    {
        public string apppath = System.AppDomain.CurrentDomain.BaseDirectory.ToString();

        public void TextLog(string msg)
        {
            try
            {
                StreamWriter sw;
                FileInfo f;
                Thread thr = Thread.CurrentThread;
                int j = 0;

             //   string s = apppath + thr.Name + " PrintDetails " + DateTime.Today.ToString("dd-MM-yyyy") + ".txt";

                string s = apppath +  " PrintDetails " + DateTime.Today.ToString("dd-MM-yyyy") + ".txt";

                f = new FileInfo(s);
                if (f.Exists)
                {
                    sw = f.AppendText();
                }
                else
                {
                    sw = f.CreateText();
                    sw.WriteLine();
                }
                sw.WriteLine("-----------------------------------------------------------------");
                sw.WriteLine(msg + "    " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff"));

                if (msg == "Service Stopped ...............")
                {

                }
                else
                {
                    for (int i = 0; i < 3000; i++)
                    {

                        Thread thr2 = Thread.CurrentThread;

                        if (thr2.Name == "Thread 1")
                        {
                            sw.WriteLine(thr2.Name + " : " + i + "    " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff"));
                        }
                        else
                        {
                            sw.WriteLine(thr2.Name + " ::: " + i + "    " + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss:ffff"));
                        }

                        Console.WriteLine(j);

                        if (j == 0)
                        {
                            j = j + 1;
                            sw.WriteLine("Thread will sleep now -----------------------------------------------------------------");
                            Thread.Sleep(1000);
                        }
                    }
                  
                }
                

                sw.Close();
            }
            catch (Exception e)
            {
                msg = e.Message;
                TextLog(msg);
            }
        }
    }
Posted
Updated 13-Jun-18 9:14am
v3

PrintDetails looks to be creating a file with its name based on the current date so using the class twice on the same day is causing a conflict. You need some way of making PrintDetails use a unique filename, maybe include the thread id in the filename as well. You haven't posted the code for the class so we can't give specific advice.
 
Share this answer
 
v2
You want two threads to write to the same file?

Then you have to use locking. That is each thread tries to get exclusive access to a shared resource (here a file) by using an appropriate function which enters a wait state until the resource is free and then locked. Then the resource can be used and is unlocked when done.

A possible solution for you (as far as I understand your code) would be making the PrintDetails() function thread safe. That is every critical section (here: checking for file existance and creating it if necessary, and writing to the file) must be guarded using locks (optionally as ReaderWriter lock), monitors, or mutexes. See Thread Synchronization (C#) | Microsoft Docs[^] for an introduction on this topic.
 
Share this answer
 
v2
In addition to Jochen's answer, you might be interested in ReaderWriterLockSlim which allows multiple threads to be in read mode, and allows one thread to be in write mode with exclusive ownership of the lock.
See example here: ReaderWriterLockSlim Class (System.Threading)[^]
 
Share this answer
 
Get rid of all your "stream writer" code and use

File.AppendAllText (path, text)


(or "append all lines").

It is more "atomic".

Quote:
Given a string and a file path, this method opens the specified file, appends the string to the end of the file, and then closes the file. The file handle is guaranteed to be closed by this method, even if exceptions are raised.

The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories.
 
Share this answer
 
v2

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900