Example #1
0
 private static FileReadWriteLock GetLock(this string filePath)
 {
     filePath = Path.GetFullPath(filePath ?? string.Empty);
     lock (locks)
     {
         if (!locks.TryGetValue(filePath, out var locker))
         {
             locks.Add(filePath, locker = new FileReadWriteLock(filePath));
         }
         return(locker);
     }
 }
Example #2
0
        private static int RunFileLocker(FileLockerOptions options)
        {
            var locker     = new FileReadWriteLock(options.FilePath);
            var tasks      = new List <Task>();
            var exceptions = new ConcurrentBag <Exception>();

            if (options.Access.HasFlag(FileAccess.Read))
            {
                tasks.Add(Task.Run(() =>
                {
                    try
                    {
                        while (!string.IsNullOrEmpty(options.StartWaitForFile) && !options.StartWaitForFile.FileExists())
                        {
                            Thread.Sleep(0);
                        }

                        var ends = DateTime.UtcNow.AddMilliseconds(options.RetryDurationMs);
                        while (DateTime.UtcNow < ends)
                        {
                            using (locker.AcquireRead())
                            {
                                if (options.Verbose)
                                {
                                    Console.WriteLine("Data accessed to read");
                                }

                                if (options.FilePath.FileExists())
                                {
                                    using (var reader = new StreamReader(new FileStream(options.FilePath,
                                                                                        FileMode.Open, FileAccess.Read, FileShare.Read)))
                                    {
                                        var text = reader.ReadLine();
                                        if (options.Verbose)
                                        {
                                            Console.WriteLine("Data read : {0}", text);
                                        }
                                    }
                                }
                            }
                            Thread.Sleep(0);
                        }
                    }
                    catch (Exception e)
                    {
                        exceptions.Add(e);
                    }
                }));
            }

            if (options.Access.HasFlag(FileAccess.Write))
            {
                tasks.Add(Task.Run(() =>
                {
                    try
                    {
                        while (!string.IsNullOrEmpty(options.StartWaitForFile) && !options.StartWaitForFile.FileExists())
                        {
                            Thread.Sleep(0);
                        }

                        var ends = DateTime.UtcNow.AddMilliseconds(options.RetryDurationMs);
                        while (DateTime.UtcNow < ends)
                        {
                            using (locker.AcquireWrite())
                            {
                                if (options.Verbose)
                                {
                                    Console.WriteLine("Data accessed to write");
                                }


                                using (var writer = new StreamWriter(new FileStream(options.FilePath,
                                                                                    FileMode.OpenOrCreate,
                                                                                    FileAccess.Write, FileShare.None)))
                                    writer.WriteLine("Hello my data");

                                if (options.Verbose)
                                {
                                    Console.WriteLine("Data wrote");
                                }
                            }
                            Thread.Sleep(0);
                        }
                    }
                    catch (Exception e)
                    {
                        exceptions.Add(e);
                    }
                }));
            }

            tasks.ForEach(p => p.Wait());

            if (exceptions.IsEmpty)
            {
                return(0);
            }
            else
            {
                var sb = new StringBuilder();
                foreach (var exception in exceptions)
                {
                    sb.AppendLine(Format(exception));
                }
                File.WriteAllText($"{Guid.NewGuid():N}.errors.log", sb.ToString());
                return(-1);
            }
        }
Example #3
0
        public void TestFileReadWriteLock()
        {
            const int iterations = 100;
            var       fileName   = $"{Guid.NewGuid():N}.dat";
            var       mre        = new ManualResetEvent(false);
            var       counters   = new int[6];
            var       locked     = counters.Select(p => FileAccess.ReadWrite).ToArray();

            var threads = Enumerable.Range(0, counters.Length)
                          .Select(p => Task.Run(() =>
            {
                var locker = new FileReadWriteLock(fileName);
                mre.WaitOne();

                if (p % 3 == 0)
                {
                    // Writer
                    for (var i = 0; i < iterations; i++)
                    {
                        using (locker.AcquireWrite())
                        {
                            // Check only 1 writer and no readers at a time
                            Assert.IsTrue(locked.All(l => l == FileAccess.ReadWrite), "Writer concurrency detected");
                            locked[p] = FileAccess.Write;

                            counters[p] += 1;
                            Thread.Sleep(5);

                            locked[p] = FileAccess.ReadWrite;
                        }
                    }
                }
                else
                {
                    // Reader
                    for (var i = 0; i < iterations; i++)
                    {
                        using (locker.AcquireRead())
                        {
                            // Check readers but no writer at a time
                            Assert.IsTrue(locked.All(l => l == FileAccess.ReadWrite || l == FileAccess.Read), "Reader concurrency detected");
                            locked[p] = FileAccess.Read;

                            counters[p] += 1;
                            Thread.Sleep(0);

                            locked[p] = FileAccess.ReadWrite;
                        }
                    }
                }
            })).ToList();

            // Starts all threads
            mre.Set();

            threads.ForEach(p => p.Wait());

            foreach (var counter in counters)
            {
                Assert.AreEqual(iterations, counter);
            }
        }