【问题标题】:Stopping a thread after all other threads I've created in the same process die在我在同一进程中创建的所有其他线程死亡后停止线程
【发布时间】:2014-06-16 19:53:06
【问题描述】:

我正在尝试编写一个任何进程都可以用于日志记录的库。我想在我的类中有一个专用的工作线程,它通过某种机制(管道、TCP 套接字等)将日志消息写入远程机器上的另一个进程,以便日志构造函数的代码看起来像这样(这样做的原因这样做是为了在远程机器上的日志服务器关闭的情况下,您不会阻止正在记录的线程停止执行):

public LogWriter()
{
    queueWriter = new Thread(() =>
    {
        while (messageQueued.WaitOne())
        {
            Message message;
            while (messageQueue.TryDequeue(out message))
            {
                bool successful = false;
                while (!successful)
                {
                    try
                    {
                        _logger.PostMessage(message);
                        successful = true;
                    }
                    catch
                    {
                        try
                        {
                            _logger = new Logger();
                        }
                        catch { }
                    }
                }
            }
        }
    });
    queueWriter.Start();
}

所以如果你有一个应用程序,你可以像这样记录:

LogWriter logWriter = new LogWriter();
logWriter.Debug("This is an example of how you'd send a debug log to the writer. This message would get translated into a Message object, queued up, and the dedicated writer would be signaled to start writing queued messages.");

messageQueue 是一个ConcurrentQueue<Message>。我希望queueWriter 总是停止十秒在我在托管它的进程中明确创建的所有其他线程(除了它自己)死后给它一些时间来完成写入它在其messageQueue 中的日志,但不要阻止进程关闭(所以十秒钟后,如果它还没有完成写入所有日志,我们不再关心,只需停止线程)。

注意事项:

  • queueWriter 成为后台线程还不够好。我不想在父线程终止时杀死queueWriter,因为它可能没有足够的时间来完成写入其挂起的日志。
  • 订阅Process.GetCurrentProcess().Exited 也不够好。 queueWriter 线程保持进程正常运行。
  • 我希望它可以用作库,并且我不希望开发人员在应用程序或进程关闭十秒后手动通知工作人员停止。我只是希望能够跟踪除工作线程之外的所有线程何时死亡,等待十秒钟,然后关闭工作线程。
  • Process.GetCurrentProcess().Threads.Count 可能很方便,但是用它做一些测试,它会为您提供应用程序使用的所有线程(如非托管线程、库线程,甚至是您没有明确创建的线程你自己,从某种意义上说,你还没有编写代码来显式启动该线程)。

那么如何做到这一点呢?有可能吗?

【问题讨论】:

  • 我认为你不能用线程来做到这一点。不过,您可以使用单独的流程。
  • 很可能是不可能的。您实际上并没有办法知道进程中的每个线程都做了什么,因此即使您枚举了每一个线程,主机进程也总是有可能做出您无法确定的安排。
  • @Jon 不是进程中的每个线程,而是库本身创建的每个线程,如果我没看错的话。
  • @zespri:它说“但不阻止进程关闭”——我读到“我想知道进程何时退出,以便我可以对我的线程进行倒计时”。
  • @KrisVandermotten 我认为你是对的。我想得越多,就越有必要使用第二个本地进程来处理这个问题。如果该进程尚未启动,该库可以将其启动,甚至订阅它,以便它拥有一个调用它的进程列表,因此它实际上可以在完成写入所有日志后自行关闭所有原始的,调用过程都死了。是的,我想就是这样。除非有人有更好的解决方案来获取您明确创建的线程数,否则这可能是唯一的方法,即使有一些警告。

标签: c# .net windows multithreading process


【解决方案1】:

您不能对线程执行此操作。不过,您可以使用单独的流程来完成。

您可能会添加队列,因为网络可能很慢且不可靠。但是与同一台机器上的进程通信速度很快,足以同步通信。你可以监控这个过程,如果它死了就启动一个新的。

【讨论】:

  • 唯一的其他选择就是承认日志记录是尽最大努力发生的。如果在事务提交之前断电,即使是持久的事务队列也不能保证消息传递。如果这是尽力而为,后台线程可能是可以接受的。这肯定会更容易。
猜你喜欢
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多