0

The error occurs randomly, my guess is when there is heavy traffic, but i'm having a hard time replicating it. This functionality runs everytime a business transaction is initiated.

Error: System.IO.IOException: The process cannot access the file '' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

private void writeToTrafficLogFile(string data, string filePath)
    {
        try
        {
            StreamWriter logWriter;

            if (!File.Exists(filePath))
            {
                logWriter = new StreamWriter(filePath);
            }
            else
            {
                logWriter = File.AppendText(filePath);
            }

            logWriter.WriteLine(DateTime.Now);
            logWriter.WriteLine(data);
            logWriter.WriteLine();

            logWriter.Close();

        }
        catch (Exception error) {
            sendLoggingErrorEmail(error, "Error Writing writeToTrafficLogFile", "Error Writing writeToTrafficLogFile.\r\n");
        }
    }

    #endregion
}
Jeremy Thompson
  • 52,213
  • 20
  • 153
  • 256
user697698
  • 45
  • 8
  • See this question http://stackoverflow.com/questions/1160233/concurrent-file-write Also I see that you're closing the logwriter, but it's in your try block, if it fails to write it won't close! You should put that close in a finally block and move the `logWriter` declaration outside of the try block (so that it's available in the finally block). – The Muffin Man Jun 25 '13 at 23:23
  • possible duplicate of [Is there a way to check if a file is in use?](http://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use) – Jeremy Thompson Jun 25 '13 at 23:26

2 Answers2

3

It might be easier and more bulletproof to switch to an existing, well tested logging solution. Several exist, have a look at dotnetlogging.com where dozens are listed. I can't recommend any, right now I am stuck with log4net but I can't recommend it.

fvu
  • 31,143
  • 5
  • 57
  • 77
  • Logging is pretty easy to accomplish. (Have a look at my answer for an easy and effectively-unbreakable solution)... don't outsource everything or you'll be destroyed when one part requires an update but another outsourced part requires you don't update and a third (......) - if you're "stuck with" it and you "can't recommend it", perhaps you should just save some trouble and pain by doing it yourself? – mcmonkey4eva Jun 25 '13 at 23:22
  • 1
    @mcmonkey4eva You're totally wrong, logging is not as easy as you seem to think (been there, done that) - at least not easy to do **right**. And I'm "stuck" because on the particular project I'm working on it was decided to use log4net but although it claims to be derived from log4j it's a much bigger pain to use. But that is just my opinion which I offered as such - I'm convinced other people will like & recommend it. – fvu Jun 25 '13 at 23:26
  • 1
    @mcmonkey4eva: that is a _terribly easy_ "solution" to break. I'm with fvu on this: logging can be hard to do _right_, and is easy to miss corner conditions. I'm in total favour of leveraging an existing logging framework. The last thing you need is your logging API/library/framework to be failing since it's what you use to log/debug and most, if not all, of your application depends on it or uses it. – Chris Sinclair Jun 25 '13 at 23:40
0

You're probably calling that from multiple threads at the same time...

There are two possible solutions:

A: Create a single thread that writes to the log file from a string that other threads can write to. -- Clarification edit: Have a class with code like

public static List<string> logme = new List<string>();
// Launch LogLoop as a thread!
public static void logloop()
{
     while (true)
     {
          while (logme.Count > 0)
          {
              File.AppendAllText("log.txt", logme[0] + "\r\n");
              logme.RemoveAt(0);
          }
          Thread.Sleep(500);
     }
}
// Oh, and whenever you want to log something, just do:
logme.add("Log this text!");

B: Use a Lock on the log writer.

mcmonkey4eva
  • 1,343
  • 7
  • 19
  • i've addeded more code. I think it's because it's trying to access it fro multiple threads for sure. – user697698 Jun 25 '13 at 23:16
  • I've add the code for a quick and easy solution to my answer. – mcmonkey4eva Jun 25 '13 at 23:18
  • Thank you, I will give this a try and if it works i'll come back and mark your answer. – user697698 Jun 25 '13 at 23:20
  • [Removing from a list is pretty expensive operation](http://stackoverflow.com/questions/5880851/what-is-the-performace-difference-in-using-listt-vs-linkedlistt-say-in-the) – fvu Jun 25 '13 at 23:27
  • Suddenly: thread-safety issues. If you have multiple threads reading/writing/altering `logme` simultaneously, you're gonna have a bad time. – Chris Sinclair Jun 25 '13 at 23:38
  • Not to mention in a _web_ context (which it sounds like it may be the case) even `static` code isn't shared between multiple application pools and request/responses. This can (and probably will) still throw file access exceptions if it's used in a traditional ASP.NET site that has multiple worker processes. – Chris Sinclair Jun 25 '13 at 23:52
  • A: I've attempted to break List editing but it seems to either be thread safe, or all my attempts were insufficient. I'm not sure on that one. B: If this code is implemented properly, it will most certainly not throw file access exceptions. The point is to make sure it is a thread running once and precisely once. Not once for each client or anything like that. – mcmonkey4eva Jun 26 '13 at 00:47