【发布时间】:2019-02-27 02:46:24
【问题描述】:
我正在想办法在我的应用程序退出/终止/等情况下关闭前台线程。
根据我测试和阅读的内容,据我了解,主线程始终是最后执行的。总是这样吗?
如果是这样,那么有人可以建议一种方法来优雅地发出关闭前台线程的信号吗? (在应用程序退出的情况下)或者这甚至可能吗?
我有点感觉前台线程应该负责关闭自己(不依赖外部信号),除非知道进程不会过早终止/关闭。这也是真的吗?
我使用前台线程而不是后台线程有几个原因:
我的线程使用
Marshal.AllocHGlobal分配[ThreadStatic]native内存,需要适当释放。它是一个服务器应用程序,最好在关闭之前发送所有排队的数据包(不是必需的)。
例如:
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