静态记录器在单独的线程中?

发布于 2024-09-03 20:38:53 字数 1655 浏览 9 评论 0原文

我已经制作了我的记录器,它记录一个字符串,一个带有静态的静态类 所以我可以从我的整个项目中调用它,而不必创建它的实例。 非常好,但我想让它在单独的线程中运行,因为访问文件会花费时间,这

在某种程度上是可能的,最好的方法是什么?

描述有点简短,但我希望这个想法很清楚。如果没有,请告诉我。

提前致谢!

顺便说一句,我的代码的任何其他改进也是受欢迎的,我感觉并不是所有的事情都尽可能高效:

internal static class MainLogger
    {
        internal static void LogStringToFile(string logText)
        {
            DateTime timestamp = DateTime.Now;
            string str = timestamp.ToString("dd-MM-yy  HH:mm:ss ", CultureInfo.InvariantCulture) + "\t" + logText + "\n";
            const string filename = Constants.LOG_FILENAME;
            FileInfo fileInfo = new FileInfo(filename);
            if (fileInfo.Exists)
            {
                if (fileInfo.Length > Constants.LOG_FILESIZE)
                {
                    File.Create(filename).Dispose();
                }
            }
            else
            {
                File.Create(filename).Dispose();
            }
            int i = 0;
            while(true)
            {
                try
                {
                    using (StreamWriter writer = File.AppendText(filename))
                    {
                        writer.WriteLine(str);
                    }
                    break;
                }
                catch (IOException)
                {
                    Thread.Sleep(10);
                    i++;
                    if (i >= 8)
                    {
                        throw new IOException("Log file \"" + Constants.LOG_FILENAME + "\" not accessible after 5 tries");
                    }
                }
            }
        }
    }
enter code here

I've made my Logger, that logs a string, a static class with a static
so I can call it from my entire project without having to make an instance of it.
quite nice, but I want to make it run in a separate thread, since accessing the file costs time

is that possible somehow and what's the best way to do it?

Its a bit of a short description, but I hope the idea is clear. if not, please let me know.

Thanks in advance!

By the way any other improvements on my code are welcome as well, I have the feeling not everything is as efficient as it can be:

internal static class MainLogger
    {
        internal static void LogStringToFile(string logText)
        {
            DateTime timestamp = DateTime.Now;
            string str = timestamp.ToString("dd-MM-yy  HH:mm:ss ", CultureInfo.InvariantCulture) + "\t" + logText + "\n";
            const string filename = Constants.LOG_FILENAME;
            FileInfo fileInfo = new FileInfo(filename);
            if (fileInfo.Exists)
            {
                if (fileInfo.Length > Constants.LOG_FILESIZE)
                {
                    File.Create(filename).Dispose();
                }
            }
            else
            {
                File.Create(filename).Dispose();
            }
            int i = 0;
            while(true)
            {
                try
                {
                    using (StreamWriter writer = File.AppendText(filename))
                    {
                        writer.WriteLine(str);
                    }
                    break;
                }
                catch (IOException)
                {
                    Thread.Sleep(10);
                    i++;
                    if (i >= 8)
                    {
                        throw new IOException("Log file \"" + Constants.LOG_FILENAME + "\" not accessible after 5 tries");
                    }
                }
            }
        }
    }
enter code here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

两相知 2024-09-10 20:38:53

如果您将此作为练习(仅使用现成的记录器不是一个选择),您可以尝试生产者/消费者系统。

  1. 为您的记录器创建一个 Init 函数,或者使用静态构造函数 - 在其中启动一个新的 System.Threading.Thread,它只运行一个 while (true) 循环。
  2. 创建一个新的 Queue 并将您的日志记录函数排入其中。
  3. 您的 while(true) 循环会查找队列中的项目、将它们出列并记录它们。
  4. 确保在任一线程上对队列执行任何操作之前锁定队列。

If you're doing this as an exercise (just using a ready made logger isn't an option) you could try a producer / consumer system.

  1. Either make an Init function for your logger, or use the static constructor - inside it, launch a new System.Threading.Thread, which just runs through a while(true) loop.
  2. Create a new Queue<string> and have your logging function enqueue onto it.
  3. Your while(true) loop looks for items on the queue, dequeues them, and logs them.
  4. Make sure you lock your queue before doing anything with it on either thread.
鹤仙姿 2024-09-10 20:38:53

抱歉,但你可能不会重新发明轮子:
选择 log4net (或任何其他(企业)日志引擎)作为您的记录器!

sry, but you may not reinvent the wheel:
choose log4net (or any other (enterprise) logging-engine) as your logger!

只为一人 2024-09-10 20:38:53

好的,简单地说,您需要创建一个 ThreadSafe 静态类。下面是一些代码片段,您从任何线程调用的委托,它指向正确的线程,然后调用 WriteToFile 函数。

当您启动要记录日志的应用程序时,请向其传递以下内容,其中 LogFile 是日志文件的文件名和路径。

Log.OnNewLogEntry += Log.WriteToFile (LogFile, Program.AppName);

然后您想将其放入静态 Logging 类中。向导位是 ThreadSafeAddEntry 函数,这将确保您处于正确的线程中以写入代码行。

public delegate void AddEntryDelegate(string entry, bool error);

public static Form mainwin;

public static event AddEntryDelegate OnNewLogEntry;

public static void AddEntry(string entry) {
  ThreadSafeAddEntry( entry, false );
}

private static void ThreadSafeAddEntry (string entry, bool error)
    {
    try
        {
        if (mainwin != null && mainwin.InvokeRequired)  // we are in a different thread to the main window
            mainwin.Invoke (new AddEntryDelegate (ThreadSafeAddEntry), new object [] { entry, error });  // call self from main thread
        else
            OnNewLogEntry (entry, error);
        }
    catch { }
    }

public static AddEntryDelegate WriteToFile(string filename, string appName) {
    //Do your WriteToFile work here
    }
}

最后写一行...

Log.AddEntry ("Hello World!");

Ok, simply put you need to create a ThreadSafe static class. Below are some code snippets, a delegate that you call from any thread, this points to the correct thread, which then invokes the WriteToFile function.

When you start the application that you want to log against, pass it the following, where LogFile is the filename and path of your log file.

Log.OnNewLogEntry += Log.WriteToFile (LogFile, Program.AppName);

Then you want to put this inside your static Logging class. The wizard bit is the ThreadSafeAddEntry function, this will make sure you are in the correct Thread for writing the line of code away.

public delegate void AddEntryDelegate(string entry, bool error);

public static Form mainwin;

public static event AddEntryDelegate OnNewLogEntry;

public static void AddEntry(string entry) {
  ThreadSafeAddEntry( entry, false );
}

private static void ThreadSafeAddEntry (string entry, bool error)
    {
    try
        {
        if (mainwin != null && mainwin.InvokeRequired)  // we are in a different thread to the main window
            mainwin.Invoke (new AddEntryDelegate (ThreadSafeAddEntry), new object [] { entry, error });  // call self from main thread
        else
            OnNewLogEntry (entry, error);
        }
    catch { }
    }

public static AddEntryDelegate WriteToFile(string filename, string appName) {
    //Do your WriteToFile work here
    }
}

And finally to write a line...

Log.AddEntry ("Hello World!");
烟柳画桥 2024-09-10 20:38:53

在这种情况下,您所遇到的是一种典型的生产者消费者场景 - 许多线程生成日志条目,一个线程将它们写入文件。 MSDN 有一篇文章,其中包含此场景的示例代码

What you have in this case is a typical producer consumer scenario - many threads produce log entries and one thread writes them out to a file. The MSDN has an article with sample code for this scenario.

ま柒月 2024-09-10 20:38:53

对于初学者来说,您的日志记录机制通常应该避免抛出异常。通常,日志机制是写入错误的地方,因此当它们也开始出错时,事情会变得很糟糕。

我会研究 BackgroundWorker 类,因为它允许您分叉可以为您进行日志记录的线程。这样您的应用程序就不会变慢,并且引发的任何异常都会被忽略。

For starters, your logging mechanism should generally avoid throwing exceptions. Frequently logging mechanisms are where errors get written to, so things get ugly when they also start erroring.

I would look into the BackgroundWorker class, as it allows you to fork off threads that can do the logging for you. That way your app isn't slowed down, and any exceptions raised are simply ignored.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文