0

Hope you can help me with this one.i am beginner in multithreading programming with C#.

I am trying to build a program to write all numbers from range 1 to 2000 in two text files using two threads.

Every thread should write number from 1 to 2000 that not found at any of the two files "there is no duplicated numbers in the files" and every thread should't write the number that have been wrote by the another thread.

At the end if we merged the numbers of the two files we should have the numbers from 1 to 2000

Here is the source code i am trying but there is a problem in the writing for loop in the below image

i can't handle the process of writing by the two synchronized threads and i had exception:

Object synchronization method was called from an unsynchronized block of code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;

namespace Multithreading
{
    class Program
    {

       static TextWriter file2 = new StreamWriter("file2 location");
       static TextWriter file1 = new StreamWriter("file1 location");

       static void Main(string[] args)
       {
           try
           {
               int[] array = new int[2000];
               Thread thread1 = new Thread(Program.writeinfile1);
               Thread thread2 = new Thread(Program.writeinfile2);

               for (int counter = 1; counter <= 2000; counter++)
               {
                   thread1.Start(counter);
                   thread2.Start(++counter);
                   Monitor.Enter(thread1);
                   Monitor.Wait(thread1);
                   Monitor.PulseAll(thread2);
               }
           }
           catch (FileNotFoundException)
           {
               Console.WriteLine("the file you are trying to open is not found");
           }
       }

       public static void writeinfile1(object x)
       {
           int converttointx = (int)x;
           file1.WriteLine(converttointx);
           file1.Close();
       }

       public static void writeinfile2(object y)
       {
           int converttointy = (int)y;
           file2.WriteLine(converttointy);
           file2.Close();
       }
    }
}
8
  • I assume this is homework? Are there any requirements on how you're supposed to handle it? Because if not, it's really as simple as looping and adding 2 to each loop and writing the result. Commented Nov 14, 2014 at 0:15
  • What's the problem, exactly? What's the error your getting; when does it break? Commented Nov 14, 2014 at 0:19
  • The result have been written into the files but it writes only one integer in each file but i don't knew what is the problem to complete the whole loop Commented Nov 14, 2014 at 0:21
  • 1
    @MohamedAdelIsmail Your code only starts the two threads once (just before the for loop), thus they only write once. Commented Nov 14, 2014 at 0:26
  • What behaviour do you want - you could kick off two threads that just spit out 1000 numbers each, starting one at 1 and one at 1001. Alternatively they could have a shared marker to show what they've written up to, locking then updating it each time they output another number. Commented Nov 14, 2014 at 0:35

2 Answers 2

2

Here's an example of multi-threaded calls talking to one another to ensure they don't duplicate work. I've not done exactly what you've asked for, since this looks quite homeworky; but hopefully this will help you to figure out the solution to your issue...

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace StackOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program();
            Console.WriteLine("done");
            Console.ReadKey();
        }
        Program()
        {
            int noThreads = 5;
            int target = 2000;
            StartThread(noThreads, target);
        }

        //kicks off our threads / waits for all threads to complete before returning
        void StartThread(int noThreads, int target)
        {
            int id = noThreads--;
            if (id > 0)
            {
                Doer doer = new Doer(id, target);
                Thread t = new Thread(doer.Do);
                t.Start();
                StartThread(noThreads,target);
                t.Join();
            }
        }


    }

    class Doer 
    {
        static int marker = 0;
        static readonly object syncLocker = new object();
        readonly int id;
        readonly int target;

        public Doer(int id, int target)
        {
            this.id = id;
            this.target = target;
        }

        public void Do() 
        {
            while (marker < this.target)
            {
                int i;
                lock (syncLocker)
                {
                    i = ++marker;
                }
                System.Console.WriteLine("{0:00}: {1:###0}", id, i);
                //Thread.Sleep(RandomNo()); //uncomment this & code below if your threads are taking turns / behaving too predictably
            }
        }


        /*
        static readonly Random rnd = new Random();
        static readonly object rndSyncLocker = new object();
        public static int RandomNo()
        {
            lock (rndSyncLocker)
            {
                return rnd.Next(0, 1000); 
            }
        }
        */

    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You are not using the Monitor class correctly. The call to Monitor.PulseAll(thread2); should be called within thread the thread which owns the lock, which in this case would be within the writeinfile1 and writeinfile2 method.

This is why you are getting the exception:

Object synchronization method was called from an unsynchronized block of code.

See the following StackOverflow question for the correct way to use Monitor.PulseAll(object):

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.