Unity 使用多线程来写日志文件

目的

自动写日志文件功能,但是不能影响游戏性能,故使用多线程来写日志。

源码

/// 
/// 日志文件模块,使用多线程来进行写日志文件
/// 
public class LogFileModule
{
    private static LogFileModule sLogFileModule;
 
    /// 
    /// 开启写日志
    /// 
    public static void Open()
    {
        if (sLogFileModule == null)
        {
            sLogFileModule = new LogFileModule();
        }
    }
 
    public static void Close()
    {
        if (sLogFileModule != null)
        {
            sLogFileModule.Dispose();
            sLogFileModule = null;
        }
    }
 
    #region 私有
 
    private class LogData
    {
        public string log { get; set; }
        public string trace { get; set; }
        public LogType level { get; set; }
    }
 
    private StreamWriter m_StreamWriter;
    private readonly ManualResetEvent m_ManualResetEvent;
    private readonly ConcurrentQueue<LogData> m_ConcurrentQueue; // 安全队列
    private bool m_ThreadRunning;
 
    private LogFileModule()
    {
        var logFileName = string.Format("zysy-logmsg-{0}.log", DateTime.Now.ToString("yyyyMMddHHmmss"));
        var logFilePath = Path.Combine(Application.persistentDataPath, logFileName);
        m_StreamWriter = new StreamWriter(logFilePath);
 
        m_ManualResetEvent = new ManualResetEvent(false);
        m_ConcurrentQueue = new ConcurrentQueue<LogData>();
        m_ThreadRunning = true;
 
        Application.logMessageReceivedThreaded += OnLogMessageReceivedThreaded;
        var fileThread = new Thread(FileLogThread);
        fileThread.Start();
    }
 
    private void Dispose()
    {
        Application.logMessageReceivedThreaded -= OnLogMessageReceivedThreaded;
 
        m_ThreadRunning = false;
        m_ManualResetEvent.Set();
        m_StreamWriter.Close();
        m_StreamWriter = null;
    }
 
    private void OnLogMessageReceivedThreaded(string logString, string stackTrace, LogType type)
    {
        m_ConcurrentQueue.Enqueue(new LogData() { log = logString, trace = stackTrace, level = type });
        m_ManualResetEvent.Set();
    }
 
    private void FileLogThread()
    {
        while (m_ThreadRunning)
        {
            m_ManualResetEvent.WaitOne();
 
            if (m_StreamWriter == null)
            {
                break;
            }
 
            LogData msg;
            while (m_ConcurrentQueue.Count > 0 && m_ConcurrentQueue.TryDequeue(out msg))
            {
                if (msg.level == LogType.Log)
                {
                    m_StreamWriter.Write("LogStart1----");
                    m_StreamWriter.Write(msg.log);
                }
                else if (msg.level == LogType.Warning)
                {
                    m_StreamWriter.Write("LogStart2----");
                    m_StreamWriter.Write(msg.log);
                }
                else
                {
                    m_StreamWriter.Write("LogStart3----");
                    m_StreamWriter.Write(msg.log);
                    m_StreamWriter.Write('\n');
                    m_StreamWriter.Write(msg.trace);
                }
 
                m_StreamWriter.Write("\r\n");
            }
            m_StreamWriter.Flush();
 
            m_ManualResetEvent.Reset();
            Thread.Sleep(1);
        }
    }
 
    #endregion
}

查看器

使用《Unity 控制台 Console 插件增强显示》这个插件,可以导入日志来查看:
Unity 使用多线程来写日志文件_第1张图片

你可能感兴趣的:(3.3,Unity)