代码之家  ›  专栏  ›  技术社区  ›  John Wooten

为什么在获取Ŧ文件时使用Ŧ读写锁定中共享异常?

  •  0
  • John Wooten  · 技术社区  · 6 年前

    INFO: Status Indexing column Master_State as index I5
    INFO: Status Indexing column Master_current0 as index I4
    INFO: Status Indexing column Master_qlevel as index I3
    INFO: Status Indexing column Master_received_Day as index I1
    Got sharing exception with lock!
    INFO: Status Indexing column Master_customer as index I7
    Waiting on file
    INFO: Status Indexing column Master_received_Year as index I8
    INFO: Status Indexing column Master_received_Month as index I9
    Waiting on file
    INFO: Status Indexing column seq_no as index I10
    

    下面是写消息“Got sharing exception with lock!”的代码

    private static void WriteToPath(object msg, string logPath)
    {
        while (true)
        {
            try
            { // These first two lines are to handle different users and/or
              // applications that log to the same log file.
              // If the File.Open fails because the file is in use, Exception
              // then wait and try again.
              //
                FileStream writer = File.Open(logPath, FileMode.Append);
                writer.Close();
    
                locker.AcquireWriterLock(writerTimeouts);
                try
                {
                    Interlocked.Increment(ref writes);
                    try
                    {
                        using (var logWriter = File.AppendText(logPath))
                        {
                            logWriter.WriteLine((string)msg);
                        }
                        break; // break out of the while loop as we're done.
                    }
                    catch
                    { // Here I write out the fact that I got an exception
                      // but not the long details about file sharing exception.
                        Console.Out.WriteLine("Got sharing exception with lock!");
                    }
                }
                finally
                {
                    if (locker.IsWriterLockHeld)
                        locker.ReleaseWriterLock();
                }
            }
            catch (Exception)
            {
                Interlocked.Increment(ref writerTimeouts);
                Console.Out.WriteLine("Waiting on file");
                Thread.Sleep(5000);
            }
        }
    }
    

    此写入路径的调用如下所示:

    public static void Log(string dir, string pgm, string errorLevel, string msgType, string details)
    {
        string line = null;
        if (details != null)
        {
            line = FormatLogMessage(pgm, errorLevel, msgType, details);
        }
        else
        {
            line = FormatLogMessage(pgm, "INFO", "End", BuildInfo.ApplicationName);
        }
        ThreadPool.QueueUserWorkItem(WriteWithLock, line);
    }
    
    private static void WriteWithLock(object msg)
    {
        string logPath = _cfg.getLogDirectory() + GetLogFileName();
        WriteToPath(msg, logPath);
    }
    

    这是一系列应用程序的一部分,这些应用程序使用

      ProcessStartInfo info = new ProcessStartInfo();
                info.FileName = batchFile;
                info.Arguments = argList;
                Process.Start(info);
    

    看起来Windows10应该有类似于 System.Logging.LogToFile文件(路径、消息)任何人都可以调用,系统将管理任何冲突。我找不到这样的东西,但肯定很不错!

    1 回复  |  直到 6 年前
        1
  •  0
  •   Lee Toffolo    6 年前

    这是我使用的精简版,互斥锁应该可以满足您的需要,至少这对我来说没有问题:

    public sealed class GlobalLogger : IDisposable
    {
        private static GlobalLogger Logger;
        private readonly Mutex _lock;
        private string _activityLogPath;
        private const string ActivityLogFileName =  @"activity.log";
    
        private GlobalLogger()
        {
            _lock = new Mutex(false, ActivityLogFileName);          
        }
    
        /// <summary> Finds the root path of the MSD, sets up log file. </summary>
        /// <returns>Drive info, or null if not found</returns>
        public static void Init()
        {
            if (null == Logger)
            {
                Logger = new GlobalLogger();
            }
    
            if (string.IsNullOrEmpty(_activityLogPath))
            {
                Logger._activityLogPath = ActivityLogFileName;
            }
        }
    
        //
        // Debug 
        //
        public static void DebugWriteLineInfo(object sender, string format, params object[] args)
        {
            DebugWriteMessage(sender, "I", true, format, args);
        }
    
        public static void DebugWriteLineWarning(object sender, string format, params object[] args)
        {
            DebugWriteMessage(sender, "W", true, format, args);
        }
    
        public static void DebugWriteLineError(object sender, string format, params object[] args)
        {
            DebugWriteMessage(sender, "E", true, format, args);
        }
    
        private static void DebugWriteMessage(object sender, string severity, bool writeLine, string format, params object[] args)
        {
            if (writeLine)
            {
                Debug.WriteLine(format);
            }
            else
            {
                Debug.Write(format);
            }     
        }
    
        //
        // Logging
        //
        private static void Log(string logType, string severity, object sender, string format, params object[] args)
        {
            Init();
    
            if (Logger._lock.WaitOne(250))
            {
                try
                {
                    using (StreamWriter sw = new StreamWriter(Logger._activityLogPath, true))
                    {
                        if (logType != "RAW")
                        {
                            sw.Write("{0} {1} {2} ",
                                DateTime.Now,
                                logType,
                                severity);
                        }
    
                        sw.WriteLine(format, args);
                    }
                }
                finally
                {
                    Logger._lock.ReleaseMutex();
                }
            }
        }
    
        public static void LogActivityInformation(object sender, string format, params object[] args)
        {
            Log("ACT", "I", sender, format, args);  
        }
    
        public static void LogActivityWarning(object sender, string format, params object[] args)
        {
            Log("ACT", "W", sender, format, args);  
        }
    
        public static void LogActivityError(object sender, string format, params object[] args)
        {
            Log("ACT", "E", sender, format, args);  
        }
        public static void LogApplicationInformation(object sender, string format, params object[] args)
        {
            Log("APP", "I", sender, format, args);  
        }
    
        public static void LogApplicationWarning(object sender, string format, params object[] args)
        {
            Log("APP", "W", sender, format, args);  
        }
    
        public static void LogApplicationError(object sender, string format, params object[] args)
        {
            Log("APP", "E", sender, format, args);  
        }
    
        public static void LogSystemInformation(object sender, string format, params object[] args)
        {
            Log("SYS", "I", sender, format, args);  
        }
    
        public static void LogSystemWarning(object sender, string format, params object[] args)
        {
            Log("SYS", "W", sender, format, args);  
        }
    
        public static void LogSystemError(object sender, string format, params object[] args)
        {
            Log("SYS", "E", sender, format, args);  
        }
    
        public static void LogRaw(object sender, string format, params object[] args)
        {
            Log("RAW", string.Empty, sender, format, args);
        }
    
        public void Dispose()
        {
            if (null != _lock)
            {
                _lock.Close();
            }
        }
    }