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

為{幸葍}努か 提交于 2020-01-22 19:11:09

目的

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

源码

/// <summary>
/// 日志文件模块,使用多线程来进行写日志文件
/// </summary>
public class LogFileModule
{
    private static LogFileModule sLogFileModule;
 
    /// <summary>
    /// 开启写日志
    /// </summary>
    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 插件增强显示》这个插件,可以导入日志来查看:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!