Salamander2007
Salamander2007

Reputation: 6394

File Locking (Read/Write) in ASP.NET Application

I have two ASP.NET web application. One is responsible for processing some info and writing to a log file, and the other application is reponsible for reading the log file and displays the information based on user request.

Here's my code for the Writer

public static void WriteLog(String PathToLogFile, String Message)
{
    Mutex FileLock = new Mutex(false, "LogFileMutex");
    try
    {
        FileLock.WaitOne();
        using (StreamWriter sw = File.AppendText(FilePath))
        {
            sw.WriteLine(Message);
            sw.Close();
        }    
    }
    catch (Exception ex)
    {
        LogUtil.WriteToSystemLog(ex);
    }
    finally
    {
        FileLock.ReleaseMutex();
    }
}

And here's my code for the Reader :

private String ReadLog(String PathToLogFile)
{
    FileStream fs = new FileStream(
          PathToLogFile, FileMode.Open, 
          FileAccess.Read, FileShare.ReadWrite);
    StreamReader Reader = new StreamReader(fs);
    return Reader.ReadToEnd();
}

My question, is the above code enough to prevent locking in a web garden environemnt?

EDIT 1 : Dirty read is okay. EDIT 2 : Creating Mutex with new Mutex(false, "LogFileMutex"), closing StreamWriter

Upvotes: 3

Views: 8169

Answers (4)

Mitch Wheat
Mitch Wheat

Reputation: 300489

You should also be disposing of your mutex, as it derives from WaitHandle, and WaitHandle implements IDisposable:

using (Mutex FileLock = new Mutex(true, "LogFileMutex"))
{
    // ...
}

Also, perhaps consider a more unique name (a GUID perhaps) than "LogFileMutex", since another unrelated process could possibly use the same name inadvertantly.

Upvotes: 2

JoshBerke
JoshBerke

Reputation: 67068

Sounds like your trying to implement a basic queue. Why not use a queue that gives you guarenteed availability. You could drop the messages into an MSMQ, then implement a windows service which will read from the queue and push the messages to the DB. If the writting to the DB fails you simply leave the message on the queue (Although you will want to handle posion messages so if it fails cause the data is bad you don't end up in an infinite loop)

This will get rid of all locking concerns and give you guarenteed delivery to your reader...

Upvotes: 8

Spencer Ruport
Spencer Ruport

Reputation: 35107

No it won't. First, you're creating a brand new mutex with every call so multiple threads are going to access the writing critical section. Second, you don't even use the mutex in the reading critical section so one thread could be attempting to read the file while another is attempting to write. Also, you're not closing the stream in the ReadLog method so once the first read request comes through your app won't be able to write any log entries anyway until garbage collection comes along and closes the stream for you... which could take awhile.

Upvotes: 1

Tom Anderson
Tom Anderson

Reputation: 10827

Doing this in a web based environment, you are going to have a lot of issues with file locks, can you change this up to use a database instead?

Most hosting solutions are allowing up to 250mb SQL databases.

Not only will a database help with the locking issues, it will also allow you to purge older data more easily, after a wile, that log read is going to get really slow.

Upvotes: 1

Related Questions