1

スレッド同期の簡単なプログラムを作成しました。しかし、このプログラムを実行すると、「別のプロセスで使用されているため、プロセスはファイル 'D:\Vivek.txt' にアクセスできません。」というエラーが表示されます。このエラーが発生する理由。

class Program
{
    const string Filepath = "D:\\Vivek.txt";
    static AutoResetEvent writerwaithandle= new AutoResetEvent(true);// Signaled state
    static AutoResetEvent readerwaithandle = new AutoResetEvent(false);

    static void Main()
    {

        if (File.Exists(Filepath))
        {
            File.Delete(Filepath);                                          
        }

        File.CreateText(Filepath);
        CreateWriterThread();
        CreateReaderThread();
        Console.ReadKey();
    }

    private static void CreateWriterThread()
    {
        for (int i = 1; i <= 10;i++ )
        {

            var thread = new Thread(WriteFile);
            thread.Name = "Writer " + i;
            thread.Start();
            Thread.Sleep(250);
        }

    }

    private static void CreateReaderThread()
    {
        for (int i = 1; i <= 10; i++)
        {
            var thread = new Thread(ReadFile);
            thread.Name = "Reader " + i;
            thread.Start();
        }
    }

    private static void WriteFile()
    {
        writerwaithandle.WaitOne();

        var stream = new FileStream(Filepath, FileMode.Append);
        var streamwriter = new StreamWriter(stream);
        streamwriter.WriteLine("written by"+Thread.CurrentThread.Name+DateTime.Now));
        streamwriter.Flush();
        streamwriter.Close();

        readerwaithandle.Set();
    }

    private static void ReadFile()
    {
        readerwaithandle.WaitOne();
        if (File.Exists(Filepath))
        {
            var stream = new FileStream(Filepath, FileMode.Open);
            var streamreader = new StreamReader(stream);
            var text = streamreader.ReadToEnd();
            streamreader.Close();
            Console.WriteLine("Read by thread {0} \n",Thread.CurrentThread.Name);
            Console.WriteLine(text);
        }
        writerwaithandle.Set();
    }
}

のコードを置き換えると

if (File.Exists(Filepath))
{
  File.Delete(Filepath);                                          
}
  File.CreateText(Filepath);

if (!File.Exists(Filepath))
{
  File.CreateText(Filepath);
}

プログラムは初めて同じエラーを表示します。その後、エラーが発生することはありません。バグの領域、理由、および最善の解決策を教えてください。

4

2 に答える 2

1

用心深く、のドキュメントを見てくださいFile.CreateText

UTF-8 でエンコードされたテキストを書き込むためのファイルを作成または開きます。

戻り値の型: System.IO.StreamWriter 書き込む StreamWriter

UTF-8エンコーディングを使用して指定されたファイルに

を使用すると、FileStream が既に作成されて返されているため、新しい FileStream を作成する必要がないことを意味しますFile.CreateText。コードでは、作成された FileStream のみを使用する必要があります。

コードの修正バージョンは次のとおりです。

 class Program
    {
        const string Filepath = "D:\\Vivek.txt";
        static AutoResetEvent writerwaithandle = new AutoResetEvent(true);// Signaled state
        static AutoResetEvent readerwaithandle = new AutoResetEvent(false);

        static void Main()
        {

            if (File.Exists(Filepath))
            {
                File.Delete(Filepath);
            }

            //File.CreateText(Filepath);
            CreateWriterThread();
            CreateReaderThread();
            Console.ReadKey();
        }

        private static void CreateWriterThread()
        {
            for (int i = 1; i <= 10; i++)
            {

                var thread = new Thread(WriteFile);
                thread.Name = "Writer " + i;
                thread.Start();
                Thread.Sleep(250);
            }

        }

        private static void CreateReaderThread()
        {
            for (int i = 1; i <= 10; i++)
            {
                var thread = new Thread(ReadFile);
                thread.Name = "Reader " + i;
                thread.Start();
            }
        }

        private static void WriteFile()
        {
            writerwaithandle.WaitOne();


            var streamwriter = File.CreateText(Filepath);

            //var stream = new FileStream(Filepath, FileMode.Append);
            //var streamwriter = new StreamWriter(stream);
            streamwriter.WriteLine("written by" + Thread.CurrentThread.Name + DateTime.Now);
            streamwriter.Flush();
            streamwriter.Close();

            readerwaithandle.Set();
        }

        private static void ReadFile()
        {
            readerwaithandle.WaitOne();
            if (File.Exists(Filepath))
            {
                var stream = new FileStream(Filepath, FileMode.Open);
                var streamreader = new StreamReader(stream);
                var text = streamreader.ReadToEnd();
                streamreader.Close();
                Console.WriteLine("Read by thread {0} \n", Thread.CurrentThread.Name);
                Console.WriteLine(text);
            }
            writerwaithandle.Set();
        }
    }
于 2013-09-03T06:02:29.823 に答える