1

I have written a simple program of thread synchronization. But when I run this program I get an error "The process cannot access the file 'D:\Vivek.txt' because it is being used by another process." Why I am getting this error.

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

when I replace the code from

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

to

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

the program shows the same error for first time. after that it never gives any error. please anyone tell me the bug area, reason and what should be the best solution.

  • maybe your file is open in some other software like notepad? close it and try again. – Vandesh Sep 03 '13 at 05:35
  • 3
    `File.CreateText(Filepath);` leaves the file open. You need to close it using the return value: `File.CreateText(Filepath).Dispose();` – Matthew Watson Sep 03 '13 at 06:23
  • I am agree with you Maththew. File.CreateText(filepath) leaves the file open, so updating the code if (File.Exists(Filepath)) { File.Delete(Filepath); } var stream = File.CreateText(Filepath); stream.Close(); gives us the required result. Thanks to you for participating. – Vivek Kumar Mishra Sep 03 '13 at 07:45

2 Answers2

2

When you use FileStream always use it with using like

using (var fileStream = new FileStream(Filepath, FileMode.Open))
{
   Your code...
}

This ensures that the stream gets disposed properly.

You can also use the StreamReader along with using

using (var fileStream = new FileStream(Filepath, FileMode.Open))
{
    using (var reader = new StreamReader(stream))
    {
        Your code...
    }
}
Srinivas
  • 1,063
  • 7
  • 15
1

Be vigilant, look at the documentation of File.CreateText

Creates or opens a file for writing UTF-8 encoded text.

Return Value Type: System.IO.StreamWriter A StreamWriter that writes

to the specified file using UTF-8 encoding

It means that there is no need to create a new FileStream because FileStream is already created and returned when you use File.CreateText. You should only use that created FileStream in your code.

Here is the fixed version of your code:

 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();
        }
    }
Community
  • 1
  • 1
testCoder
  • 7,155
  • 13
  • 56
  • 75
  • I am agree with Maththew watson. File.Create(filepath) leaves the file open, so updating the code if (File.Exists(Filepath)) { File.Delete(Filepath); } var stream = File.CreateText(Filepath); stream.Close(); gives us the required result Thanks to all for participating. – Vivek Kumar Mishra Sep 03 '13 at 07:41