Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will lock prevent the error "The process cannot access the file because it is being used by another process"?

Here is my log writing function:

public static void WriteLog(string source, string message)
{
    string logFilePath = @"C:\LogFile\log.txt";
    using (StreamWriter sw = new StreamWriter(logFilePath, true))
    {
        sw.Write(source + ": :" + message);
    }
}

But this code sometimes caused me the error:

The process cannot access the file because it is being used by another process

So I modified my code a bit, and here is my new code:

public static void WriteLog(string source, string message)
{
    object _lock = new object();
    lock (_lock)
    {
        string logFilePath = @"C:\LogFile\log.txt";
        using (StreamWriter sw = new StreamWriter(logFilePath, true))
        {
            sw.Write(source + ": :" + message);
        }
    }
}

Though I haven't received an error after using this code. But still I just wanted to know if this is correct way to use lock to prevent such errors due to deadlock, and if the way I have used lock is correct or not.

like image 544
iJade Avatar asked Sep 04 '12 19:09

iJade


People also ask

How do you fix process Cannot access the file because it is being used by another process?

Applies to: Press Ctrl + Alt + Delete, then click Task Manager. Ensure you're on the Processes tab. Locate and right-click SidekickTrayWPF, then select End Process. If a warning window opens to ask if you want to end the process, click End Process again to confirm.


1 Answers

Your use of lock in your second example won't work properly anyhow because you create a new lock object and lock it every time.

What you really want file wise is something like this:

public static void WriteLog(string source, string message)
    {
        string logFilePath = @"C:\LogFile\log.txt";

        using (FileStream file = new FileStream(logFilePath,FileMode.Append,FileAccess.Write,FileShare.None)) 
        {
            StreamWriter writer = new StreamWriter(file);

            writer.write(source + ": : " + message);

            file.Flush();
            file.Close();
        }
    }

This should exclusively lock the file while you write BUT properly close off the file once done with.

This does NOT solve the threading issue, because two threads can still collide. If one thread locks the file subsequent requests will fail.

To solve this with a lock, move the lock object to a static that all threads can share and lock against, such as:

public static class Logger
{

    private static object locker = new object();

    public static void Log(string source, string message)
    {
        lock (locker) 
        {
            string logFilePath = @"C:\LogFile\log.txt";

            using (FileStream file = new FileStream(logFilePath,FileMode.Append,FileAccess.Write,FileShare.None)) 
            {
                StreamWriter writer = new StreamWriter(file);

                writer.write(source + ": : " + message);   
                writer.Flush();

                file.Close();
            }
        }
    }

}

This will cause subsequent threads to wait until the lock becomes available before writing to the file as originally expected.

Note Oded's comment though, that still applies to this method.

like image 60
Lloyd Avatar answered Oct 12 '22 23:10

Lloyd