2

Have a test class that creates log files that I write to. I want to be able to add text to the file throughout my program by referencing the LogErrors method of the class.

public class test
{
public static string errorFileName = DateTime.Now.ToString("yyyy-MM-dd") + "testerrors.csv";
public static StreamWriter errorfile =  new StreamWriter("c:\" + @"\" + errorFileName, true);


  public static void LogErrors(string error, string record)
  {
    test.errorfilewriter.WriteLine( error + "," +  record );
  }
}

Here is where I reference the class to append records to the file: If an error is encountered in my program I want to reference the method then add that line of text to the file

test.LogErrors("INVALID RECORD", string.Join(",",line));

At that line I get this error:

The type initializer for program.Test threw an excpetion.
INNER EXCEPTION: The process cannot access the file c:\2013-10-21testerrors.csv because it is being used by another process. 

The file was just created during this program so it does not exist yet and is not opened somewhere else.

EDIT:

public class test
{

   public static string errorFileName = DateTime.Now.ToString("yyyy-MM-dd") + "testERRORS.csv";
   private static object _lockObj = new Object();

  public static void LogErrors(string error, string record)
    {
        lock (_lockObj)
        {
            File.AppendAllText(Logging.errorFileName, error + "-" + record);
            //File.AppendAllLines does not exist in .NET 3.5
        }
    }

   test.LogErrors("INVALID",line));

I get past the test.LogError line and it goes to the test class but if I stop the program after it writes that line to test the file. Nothing is in the file Also can I use the the lock object for more than one file. As I'm creating a bunch of log files in this test class. How does the program know where to place the files like the c:/ as the streamwriter was declaring that.

Jt2ouan
  • 1,964
  • 9
  • 33
  • 55
  • look at the bottom (not accepted) answer [Here](http://stackoverflow.com/questions/4010543/lock-in-a-static-method/4010606#4010606) – Jonesopolis Oct 22 '13 at 15:01

2 Answers2

2

Instead of opening a writer, and leaving it open, just leverage AppendAllLines. So, in the Logging class, build a method called WriteLine:

public static void WriteLine(string line)
{
    lock (_lockObj)
    {
        File.AppendAllLines(pathToLogFile, line);
    }
}

where _lockObj is a field defined in the Logging class:

private static object _lockObj = new Object();

The locking is important here. In practice, in your example, there probably won't be more than one thread writing to it - but it's the right thing to do. You have to ensure that two threads aren't accessing that file at the same time because the operating system isn't going to protect it like that for you.

The other benefit of this approach is that the unmanaged memory that's associated with opening a file is now managed by the .NET frameworks class that is built-in and it's fully encapsulated from your code.

Mike Perrenoud
  • 66,820
  • 29
  • 157
  • 232
0

You probably have locking issues because the file is trying to be opened by two different threads.

There are many programs that are thread safe that will do this job for you.

eg http://nlog-project.org/

Edmund Covington
  • 521
  • 6
  • 17