-1

I am using a routine for catching any exception inside my project. Then i am write it inside a text file. But how can i prevent an exception if i will try to write into the txt file from two different threads?

public static void LogFile(string ex)
    {
        try
        {
            string strPath = @"C:\Log.txt";
            if (!File.Exists(strPath))
                File.Create(strPath).Dispose();

            using (StreamWriter sw = File.AppendText(strPath))
            {
                // sw.WriteLine("=============Error Logging ===========");
                sw.WriteLine("===========Start============= " + DateTime.Now);
                sw.WriteLine("Error Message: " + ex);
                //sw.WriteLine("Stack Trace: " + ex.StackTrace);
                sw.WriteLine("===========End============= " + DateTime.Now);
                sw.WriteLine();

            }
        }
        catch
        {

        }
    }

When two threads at the same time are trying to write in my LogFile.txet then i am getting exception that *txt file is been in used.

lurker
  • 56,987
  • 9
  • 69
  • 103
  • Wrap the code inside your `LogFile()` method inside a [lock statement](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement)? – Idle_Mind May 04 '19 at 16:34
  • 1
    You need to use a locking mechanism to provide exclusive access to resources shared between threads. – Daniel Mann May 04 '19 at 16:34

1 Answers1

2

you need to make your bloc syncronzed for example like the code below. There are more examples here: C# version of java's synchronized keyword?

On a side note, there are things that are not considered good practices like ignoring the exception. You might consider also using a logging library which can take care about multi-threading, performance and such...

static object Lock = new object();




public static void LogFile(string ex)
    {
lock (Lock) {
        try
        {
            string strPath = @"C:\Log.txt";
            if (!File.Exists(strPath))
                File.Create(strPath).Dispose();

            using (StreamWriter sw = File.AppendText(strPath))
            {
                // sw.WriteLine("=============Error Logging ===========");
                sw.WriteLine("===========Start============= " + DateTime.Now);
                sw.WriteLine("Error Message: " + ex);
                //sw.WriteLine("Stack Trace: " + ex.StackTrace);
                sw.WriteLine("===========End============= " + DateTime.Now);
                sw.WriteLine();

            }
        }
        catch
        {

        }
    }
}
Dr Phil
  • 833
  • 6
  • 18
  • Ohh! thank you for your fast reply! Just two quick questions and i will mark it as answer! First question, do i need to set my static field as readonly? example static readonly object Lock = new object(); And second question, in case i want to read my file, is it better to use ReaderWriterLock or Interlocked instead of lock? Or it has the same results? – – user10775950 May 04 '19 at 17:02
  • You don't have to make the field read-only. It could be, thought, to mark the intention of not planning on modifying the lock object. – Dr Phil May 05 '19 at 00:57
  • First you have to clarify how you want to read your file. If it will be done by another process, then it (the reader) doesn't care how the writer does its internal locking. If you want to use the same process, then doing a file I/o could be quite slow. – Dr Phil May 05 '19 at 01:33
  • I don't see any benefit of using something more complicated than a simple lock for your case. Interlocked and reader writer locked are intended as performance improvement over the simple lock but are applicable only to specific scenarios. – Dr Phil May 05 '19 at 01:41