How to lock a method so that others do not call while it is used?

Asked

Viewed 54 times

2

I have a simple method of log, which adds some lines to a special file.

The problem is, the application is multi-threading, and in each Thread is called this method to log, and when one is called, it hangs and opens the file only to that instance where the method was called, and if the other Thread calls, is thrown error saying the file is already being used.

Let’s explain with the following:

inserir a descrição da imagem aqui

In the image above, Thread 1 called the method Log at the same time as the Thread 2 called, and what happened? Log did not know how to deal with the two calling at once and a half that "divided the logs", creating two instances of the same method, thus only one Log can write to the file, and the other will throw an error since the file is already being used.

The body of the method Log is as follows:

    public enum LogType
    {
        Errr = 0,
        Warn = 1,
        Info = 2
    }

    public static void Log(LogType typ, string str)
    {
        string k = string.Format("{0,-8} {1,-15} {4,4} {5,7} {2,4} : {3}", "Program", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(), typ.ToString(), str, DateTime.Now.Millisecond, pid);

        string path = GetAppData() + "\\" + "log.txt";
        using (FileStream file = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read))
        using (StreamWriter writer = new StreamWriter(file, Encoding.UTF8))
        {
            writer.Write(k.ToString() + "\n");
        }
    }

Can be easily called anywhere in the code.

How do I fix this? There are ways to bypass or crash this method so that other calls "wait" for it to be finished and avoid file congestion?

1 answer

3


Have a look at the documentation here. You already have an answer on the subject here.

public class SuaClasse
{
    private readonly object balanceLock = new object();
    public static void Log(LogType typ, string str)
    {
        lock (balanceLock)
        {
            string k = string.Format("{0,-8} {1,-15} {4,4} {5,7} {2,4} : {3}", "Program", DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(), typ.ToString(), str, DateTime.Now.Millisecond, pid);

            string path = GetAppData() + "\\" + "log.txt";
            using (FileStream file = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read))
            using (StreamWriter writer = new StreamWriter(file, Encoding.UTF8))
            {
                writer.Write(k.ToString() + "\n");
            }
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.