使用多线程使用C#写入文本文件

时间:2014-11-14 00:12:37

标签: c# multithreading file

希望你能帮我解决这个问题。我是C#多线程编程的初学者。

我正在尝试构建一个程序,使用两个线程在两个文本文件中写入范围1到2000的所有数字。

每个线程都应该写入1到2000之间的数字,这两个文件中没有找到“文件中没有重复的数字”,并且每个线程都不应该写下另一个线程编写的数字。 / p>

最后,如果我们合并两个文件的编号,我们应该有从1到2000的数字

这是我正在尝试的源代码,但在下面的图像中写入循环存在问题

我无法处理两个同步线程的写入过程,我有exception

  

从非同步代码块调用对象同步方法。

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();
       }
    }
}

2 个答案:

答案 0 :(得分:2)

以下是多线程通话的示例,以确保他们不会重复工作。 我没有完全按照你所要求的那样做,因为这看起来很像家庭作业;但希望这可以帮助您找出解决问题的方法......

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); 
            }
        }
        */

    }
}

答案 1 :(得分:0)

您没有正确使用Monitor课程。对Monitor.PulseAll(thread2);的调用应称为within thread the thread which owns the lock,在这种情况下,该调用将在writeinfile1writeinfile2方法中。

这就是你得到例外的原因:

  

从非同步代码块调用对象同步方法。

有关使用Monitor.PulseAll(object)的正确方法,请参阅以下StackOverflow问题: