C# 如何在函数之间传递对象

C# 如何在函数之间传递对象,c#,winforms,C#,Winforms,这让我有点发疯,所以如果有人能帮我,我将非常感激 我正在尝试将我的信息记录到日志文件中,因此使用了Logger类 **Logger.cs** public class Logger : IDisposable { private readonly FileStream _file; //Only this instance have a right to own it private readonly StreamWriter _writer; private rea

这让我有点发疯,所以如果有人能帮我,我将非常感激

我正在尝试将我的信息记录到日志文件中,因此使用了Logger类

**Logger.cs**

 public  class Logger : IDisposable
{
    private readonly FileStream _file; //Only this instance have a right to own it
    private readonly StreamWriter _writer;
    private readonly object _mutex; //Mutex for synchronizing

    /// <summary>
    /// Call this function to use the text file
    /// </summary>
    /// <param name="logPath"></param>
    public Logger(string logPath)
    {
        if (logPath != null) _file = new FileStream(logPath, FileMode.Append);
        _writer = new StreamWriter(_file);
        _mutex = new object();
    }

    // Log is thread safe, it can be called from many threads
    public void Log(string message)
    {
        lock (_mutex)
        {
           //_writer.Write("\r\nLog Entry : ");
           // _writer.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
           //DateTime.Now.ToLongDateString());

            _writer.WriteLine("{0} {1}", DateTime.Now.ToString("yyyy-MM-dd"),
          DateTime.Now.ToLongTimeString());
            _writer.WriteLine(message);
        }
    }

    /// <summary>
    /// Call this function when it says file is already been using somewhere
    /// </summary>
    public void Dispose()
    {
        _writer.Dispose(); //Will close underlying stream
    }
}
**我的函数使用相同的记录器路径**

 private void MigrateProductStats(object corporationIdObj, object brandIdObj, object logFilePath)
    {
         _logger = new Logger(logFilePath.ToString());
        _logger.Log("Am I still writing to same file?");
        _logger.Dispose();
        for (int i = 0; i <= 10;i++ )
        {
            DoProductStatsForCorporation(123, logFilePath.ToString());
        }

    }
    private void DoProductStatsForCorporation(int corporationId, string logFilePath)
    {
        _logger = new Logger(logFilePath);
        _logger.Log("Am I still writing to same file second time?");
        _logger.Dispose();
    }
在上述情况下,在我的按钮单击中,我正在处理logger并将路径发送到函数DoProductStatsForCorporation和MigrateProductStats,而不是如果我尝试发送_logger对象而不处理该对象,并避免在我的子函数中重新调用,我将收到一个错误,该错误无法写入该文件,因为该文件正被其他人使用过程

我希望这是有道理的


如果您能提供任何有关这方面的指导,我将不胜感激,因为我一直在想该怎么做。

您遇到的问题是它是MT,很可能您正在写入一个已经打开的文件(比赛条件)

为什么不为你的记录器/写入程序使用单例呢?为什么不锁定编写器,只使用一个实例,而不总是创建一个新实例

另外,您的路径字符串看起来确实错误。我的意思是,为什么要在文件名中每隔一毫秒/勾选一次


我建议您使用单例方法进行日志记录,或者如果必须的话,创建日志记录程序的静态实例,并在写入时锁定文件,完成后进行处置。您正在写入可能正在使用的文件,而其他线程正在访问该文件。请确保文件名也是唯一的-它可能与代码中您认为的不一样。

我有点困惑。为什么要将文件路径传递给记录器?它可能应该控制它自己。就我个人而言,我会将我的Logger类设置为静态,然后像这样同步方法:

[MethodImpl(MethodImplOptions.Synchronized)]
public static void Log(string description)
然后,使用并处理writer内联以避免这些问题

using (var writer = new StreamWriter(Path + "\\" + LOG_FILE, true))
{
    writer.WriteLine(log);
    writer.Close();
}

对于初学者
DoProductStatsForCorporation
logger不应是此函数的参数。 您的日志应该在开始时创建,并在类中创建一个字段

您不希望将记录器传递给函数,因为函数实际上不需要此记录器来完成其工作

将logger移出一些按钮代码,在构造函数中创建它,并在发生日志记录的类的私有字段中使用like

如果要更改同一类中的日志文件并记录到不同的文件,则必须重写logger类,以便它可以使用多个文件


您还可以了解Log4net,它真的很不错。

您可以使用一个库来为您实现这一点,而不是重新创建自己的库。例如Log4net。
[MethodImpl(MethodImplOptions.Synchronized)]
public static void Log(string description)
using (var writer = new StreamWriter(Path + "\\" + LOG_FILE, true))
{
    writer.WriteLine(log);
    writer.Close();
}