【问题标题】:Shutting down a foreground thread on application quit?在应用程序退出时关闭前台线程?
【发布时间】:2019-02-27 02:46:24
【问题描述】:

我正在想办法在我的应用程序退出/终止/等情况下关闭前台线程。

根据我测试和阅读的内容,据我了解,主线程始终是最后执行的。总是这样吗?

如果是这样,那么有人可以建议一种方法来优雅地发出关闭前台线程的信号吗? (在应用程序退出的情况下)或者这甚至可能吗?

我有点感觉前台线程应该负责关闭自己(不依赖外部信号),除非知道进程不会过早终止/关闭。这也是真的吗?

我使用前台线程而不是后台线程有几个原因:

  1. 我的线程使用Marshal.AllocHGlobal分配[ThreadStatic]native内存,需要适当释放。

  2. 它是一个服务器应用程序,最好在关闭之前发送所有排队的数据包(不是必需的)。

例如:

 volatile bool running = true;

 static void Main()
        {
            AppDomain.CurrentDomain.ProcessExit += new 
            EventHandler(OnProcessExit);
            var t = new Thread(ReadWrite);
            t.Start();
            ConsoleKeyInfo cki;
            Console.WriteLine("Running..\n");
            bool stopped = false;
            while(!stopped)
            {
                // do server stuff..
                   .......

                if (Console.KeyAvailable)
                {
                    cki = Console.ReadKey(true);
                    if (cki.Key == ConsoleKey.X)
                    {
                        stopped = true;
                    }
                }
            }
        }

    private void ReadWrite()
    {
        while (running)
        {
            // do stuff....
               ....

            Thread.Sleep(15);
        }
        FreeMemory();
    }


    public void EndServer()
    {
        FreeMemory();
        running = false;
        // do other stuff...
    }

    private void OnProcessExit(object sender, EventArgs e)
    {
        EndServer();
    }

这会导致:

  • stopped 已成真
  • OnProcessExit 未被调用。 (我也尝试过显式调用EndServer(),但得到了相同的结果
  • 应用程序挂起

所以我怀疑(但我不确定)由于主线程最后执行,程序正在等待ReadWrite 完成,这意味着我正在做的事情是不可能的?

如果不可能,我会:看看是否可以使用后台线程,或者我会考虑重新设计我的本机内存实现。

【问题讨论】:

  • 为什么要担心内存分配(第 1 点)?当程序关闭时,该问题将自行解决。 blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
  • @mjwills 谢谢,我真的不知道我是怎么不找那个的!我想这解决了我的主要问题(尽管我想我从来没有真正遇到过)。
  • 可靠地清理应用程序关闭是垃圾回收内存管理的一大优势。正如我的遗嘱所说,不要理会它。第二件事是这个问题没有多大意义。只有一个 Foreground/Primary/GUI Thread 并且您不启动它。它的结尾是节目结尾的定义。它通常需要所有后台线程(至少在 .NET 中)。
  • @Christopher AFAIK 本机内存不受 GC 影响(这是我最初担心的原因)。此外,您绝对可以创建前台线程(在我的示例中创建线程时默认),这就是为什么在我的情况下程序不会退出的原因。虽然现在看我的问题,但我同意这真的没有多大意义哈哈。
  • @Bureto:如果你有非托管资源,这是 Finalize/Dispose 模式的问题。而且即使你不需要敲定,你至少需要提供一个 dispose。这是 GC、.NET 代码和非托管资源重叠的区域。

标签: c# multithreading application-shutdown


【解决方案1】:

原来我不知道程序关闭时会释放本机内存。将我的线程置于后台将解决我的其余问题。

编辑以供将来参考: 后台线程没有解决第 2 点,尽管它对我来说不是必需的,所以我还是继续使用这个解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多