【问题标题】:dedicated thread for logging .net用于记录 .net 的专用线程
【发布时间】:2013-12-20 19:35:21
【问题描述】:

我正在考虑创建一个具有专用线程的异步日志记录组件,该线程将从队列中读取新项目并写入数据库、文件等。如果我创建一个线程作为后台线程,它将在进程结束后立即终止结束,因此队列中的所有项目都将丢失。如果我创建它是一个前台 - 我将不得不弄清楚何时停止它,因为它会阻止应用程序关闭。有什么方法可以不让开发人员记住在应用程序退出之前“停止”日志记录功能?

【问题讨论】:

  • 一开始就不要创建一个专门的线程来管理它......它将花费大部分时间什么都不做。这对于日志框架来说是相当浪费的。就此而言,首先要避免编写自己的日志框架;这是一个复杂的问题,已经有许多解决方案可供您使用。
  • 这个其他问题可能会回答您的问题:How do I create an asyncronous wrapper for log4net?

标签: c# multithreading logging asynchronous


【解决方案1】:

我相信你可以:

  • 订阅AppDomain.ProcessExit事件;
  • 使用Volatile标记变量作为关机标志
  • ProcessExit 事件触发时设置标志;
  • 监控线程内标志的状态,并相应地正常关闭。

这样你可以让前台线程知道即将到来的厄运。

【讨论】:

  • 听起来 OP 无法正常关闭。听起来他的队列并不持久。
  • 似乎是这样,@JohnSaunders,我同意 - 但他似乎也可以控制专用线程的创建方式。答案可能会解决他对阻止应用程序关闭的担忧。
【解决方案2】:

首先我必须同意上面的 cmets。我只会使用 NLog 之类的东西,而不是尝试自己动手。虽然一开始似乎有很多东西要学,但它仍然比自己编写和调试要好。

如果您真的想走这条路,我的建议是使用“using”语句和 IDisposable 来控制异步行为。只需在 ctor 中启动一个普通线程并在 Dispose() 上发出信号并加入线程。

示例用法:

void Main()
{
    using (new Logging())
    {
        ...
    }
}

示例类(未经测试):

class Logging :IDisposable
{
    ManualResetEvent _stop = new ManualResetEvent(false);
    Thread _worker = null;

    public Logging()
    {
        _worker = new Thread(AsyncThread);
        _worker.Start();
    }

    public void Dispose()
    {
        _stop.Set();
        _worker.Join();
    }

    public void AsyncThread()
    {
        ... 
    }
}    

在您的日志记录例程中,您需要测试线程是否正在运行,然后决定是对日志写入进行排队还是直接附加到日志输出。这样,异步线程之前和之后的日志消息将继续正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    相关资源
    最近更新 更多