繁体   English   中英

我的代码存在任何并发问题

[英]Any Concurrency Issues with my code

我试图创建一个线程安全的方法。

有人在以下代码中看到任何并发问题吗?

在我看来,这很好, 尽管我永远无法找到一种方法来测试这种方法的并发性。 任何帮助,将不胜感激。

   //static locker for thread synchronization
   private static readonly System.Object _object3 = new System.Object();

   //this method needs to be thread-safe
   public static void LogToTextFile(string logMessage, LogLevel logType)
    {
       //make sure only one thread executes this file writing code at a time            
       lock (_object3)
        {
            using (StreamWriter w = File.AppendText(@"c:\logs\log1.txt");
            {
                w.WriteLine("\r\n{0} logged at {1} {2} : {3}", logType.ToString().ToUpper(), DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString(), logMessage);
            }
        }
    }

这段代码没有并发问题,因为由于lock语句,您只允许一个线程写入文件。

考虑到您lock范围适当的对象,因此我发现您的代码没有并发问题。

但是,正如注释中提到的millimoose一样,您存在潜在的性能问题。 如果两个线程尝试同时LogToTextFile ,则一个线程将首先获取锁,另一个线程将在打开,写入和关闭文件时阻塞。 这可能是不可接受的,具体取决于您的线程在做什么。

如果我提到的是一个问题,则必须实现更复杂的线程安全记录器。 通常,将有一个队列,日志事件会快速写入该队列。 然后有另一个线程定期唤醒,并将队列清空到磁盘上的文件。 队列上的所有操作都带有锁。

另一个可能更好的解决方案是保持文件打开状态,并使用同步的TextWriter进行写入。 TextWriter.Synchronized提供了围绕TextWriter的线程安全包装器:

对返回的包装器的所有写操作都是线程安全的。 您调用此方法以确保一次仅一个线程可以在返回的TextWriter实例上执行这些方法。

这是一个简单的实现。 注意,这尚未经过测试。

public static class MyLogger
{
    private static TextWriter s_writer;

    // Not thread-safe. Call this before other threads are allowed to call Log.
    public void Open(string filename) {
        s_writer = TextWriter.Synchronized( File.AppendText(filename) );
    }

    // Also not thread-safe.
    public void Close() {
       s_writer.Dispose();
    }

    // Thread-safe.
    public void Log(string logMessage, LogLevel logType) {
        s_writer.WriteLine("\r\n{0} logged at {1} {2} : {3}",
            logType.ToString().ToUpper(), DateTime.Now.ToLongTimeString(),
            DateTime.Now.ToLongDateString(), logMessage);
    }    
}

此特定功能内没有并发问题。 lock语句将适当地缓和对内部代码的访问。

但是,访问@"c:\\logs\\log1.txt"仍然存在潜在的并发问题。 应用程序的另一部分或同一台计算机上的另一个进程可能会尝试与代码同时写入文件。 因此,即使使用此锁定, StreamWriter代码也可能会失败。

没有办法解决这种类型的并发问题。 文件系统是一个共享资源,您没有真正的能力来保护。 取而代之的是,您的代码需要接受文件系统访问可能失败并正确处理该后果的消息。

通常,在处理日志记录功能时,我会使用try / catch包装文件系统访问权限,并吞下发生的所有异常。 否则,您将冒着日志记录功能失败的风险关闭应用程序。 对于您的方案,这可能会接受,也可能无法接受。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM