Loading color scheme

Access single file from different threads or processes and maintain consistensy without using extra locks

Sometimes you want to access a single file from different processes or threads and maintain its consistency. The example may be a common database or just a counter. When the file is opened in read-only mode, the question is trivial. But what if you want to write from different threads? Here is the code sample. The idea is to use File.Open constructor with the FileShare.None option. This option allows only one thread to access the file (either for reading or writing) and deny all other threads. The other threads should catch IOException and try to access the file subsequently with a random delay.


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

namespace FileShareTest
{
    class Program
    {
        static volatile bool MustRun = false;
        
        static void Main(string[] args)
        {
            MustRun = true;
            Thread[] threads = new Thread[5];

            for (int j = 0; j< threads.Length; j++ )
            {
                threads[j] = new Thread(ThreadFunc);
                threads[j].Start();
            }

            Console.ReadLine();

            MustRun = false;

            for (int j = 0; j < threads.Length; j++)
            {
                threads[j].Join();
            }

        }


        static void ThreadFunc()
        {
            while(MustRun)
            {
                try
                {
                    using (var fs = File.Open("test.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                    {
                        int i = 0;
                        StreamReader sr = new StreamReader(fs);
                        StreamWriter sw = new StreamWriter(fs);

                        string str = sr.ReadLine();

                        Console.WriteLine("Thrd {0}: val: {1}", Thread.CurrentThread.ManagedThreadId, str);

                        if (!string.IsNullOrEmpty(str))
                        {
                            i = int.Parse(str);
                        }



                        i++;

                        fs.Seek(0, SeekOrigin.Begin);
                        sw.WriteLine(string.Format("{0}", i));

                        sw.Flush();

                    }
                    Thread.Sleep(100);
                }
                catch (System.IO.IOException ex)
                {
                    
                    Random rnd = new Random();
                    int wait = rnd.Next(500, 1000);
                    Thread.Sleep(wait);

                    Console.WriteLine("Thrd {0}: IOException. Wait {1} ms", Thread.CurrentThread.ManagedThreadId, wait);


                }

            }

        }
    }
}

FileShareTest
Get all interesting articles to your inbox
Please wait