线程安全日志记录类的实现 [英] Thread safe logging class implementation

查看:97
本文介绍了线程安全日志记录类的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是实现相当简单的线程安全日志记录类的正确方法吗?

Would the following be the correct way to implement a fairly straightforward thread-safe logging class?

我知道我从来没有明确关闭TextWriter,这会有问题吗?

I know that I never explicitly close the TextWriter, would that be a problem?

当我最初使用TextWriter.Synchronized方法时,它似乎不起作用,直到我在静态构造函数中对其进行了初始化并将其设置为只读,如下所示:

When I initially used the TextWriter.Synchronized method, it did not seem to work until I initialized it in a static constructor and made it readonly like so:

public static class Logger
{
    static readonly TextWriter tw; 

    static Logger()
    {
        tw = TextWriter.Synchronized(File.AppendText(SPath() + "\\Log.txt")); 
    }

    public static string SPath()
    {
        return ConfigManager.GetAppSetting("logPath"); 
    }

    public static void Write(string logMessage)
    {
        try
        {
            Log(logMessage, tw);
        }
        catch (IOException e)
        {
            tw.Close();
        }
    }

    public static void Log(string logMessage, TextWriter w)
    {
        w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
            DateTime.Now.ToLongDateString());
        w.WriteLine("  :");
        w.WriteLine("  :{0}", logMessage);
        w.WriteLine("-------------------------------");

        // Update the underlying file.
        w.Flush();
    }
}

推荐答案

在这里,我将采用与其他答案完全不同的方法,并假设您实际上想学习如何编写更好的线程感知代码,并且不会从我们这里寻求第三者的建议(即使您最终可能会使用一个.)

I'm going to take a completely different approach here than the other answers and assume you actually want to learn how to write better thread-aware code, and are not looking for 3rd party suggestions from us (even though you may actually end up using one.)

正如其他人所说,您正在创建线程安全的TextWriter,这意味着对WriteLine的调用是线程安全的,这并不意味着对WriteLine的大量调用将作为原子操作执行.我的意思是,不能保证四个WriteLine调用将按顺序进行.您可能具有线程安全的TextWriter,但是没有线程安全的Logger.Log方法;)为什么?因为在这四个调用期间的任何时候,另一个线程可能会决定也调用Log.这意味着您的WriteLine呼叫将不同步.解决此问题的方法是使用lock语句,如下所示:

As others have said, you are creating a thread safe TextWriter which means calls to WriteLine are thread-safe, that doesn't mean that a bunch of calls to WriteLine are going to be performed as an atomic operation. By that I mean there is no guarantee that the four WriteLine calls are going to happen in sequence. You may have a thread-safe TextWriter, but you don't have a thread-safe Logger.Log method ;) Why? Because at any point during those four calls, another thread might decide to call Log also. This means your WriteLine calls will be out of sync. The way to fix this is by using a lock statement like so:

private static readonly object _syncObject = new object();

public static void Log(string logMessage, TextWriter w)    {
   // only one thread can own this lock, so other threads
   // entering this method will wait here until lock is
   // available.
   lock(_syncObject) {
      w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
          DateTime.Now.ToLongDateString());
      w.WriteLine("  :");
      w.WriteLine("  :{0}", logMessage);
      w.WriteLine("-------------------------------");
      // Update the underlying file.
      w.Flush();
   }
}

所以,现在您有了一个线程安全的TextWriter和一个线程安全的Logger.

So, now you have a thread-safe TextWriter AND a thread-safe Logger.

有道理吗?

这篇关于线程安全日志记录类的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆