gpt4 book ai didi

c# - 由于 AutoResetEvent 信号处于 WaitOne 状态,线程在应用程序终止后仍然存在

转载 作者:行者123 更新时间:2023-11-30 14:39:19 24 4
gpt4 key购买 nike

我有一个应用程序在队列中使用 AutoResetEvent (WaitOne/Set) 来处理消息。我注意到,当我从 Visual Studio (Shift+F5) 终止调试 session 时,应用程序的原始进程会挂起(但并非总是如此)。我手动将调试器重新附加到进程,并看到它有一个线程卡在 WaitHandle.WaitOne 上。

所以我的问题是,终止可能处于 WaitOne 状态的线程的正确方法是什么?

我想到的第一个答案是监听 Application Exit 事件并在那里做一个 Set,但我不确定在这些调试 session 之后是否可靠地调用了这个事件,或者我是否有更标准的做法我不知道。

并且,作为第二个问题,对于在“生产”模式下运行的应用程序,您会以不同的方式处理这个问题吗?

最佳答案

有一种简单的方法可以做到这一点(不是解决方法)

首先,您需要设置一个事件,在您的应用程序即将结束时触发

// somewhere with global scope. On a singleton or in program class maybe
// this is set when you want to terminate your application
private static ManualResetEvent ExitWaitHandle = new ManualResetEvent(false);

这是在其他地方使用它的方法

// the event you want to check but it's blocking your application termination
private static AutoResetEvent yourEvent = new AutoResetEvent(true);

// the method where you have the problem
private static void FooAsync()
{
try
{
WaitHandle.WaitAny(new WaitHandle[]{yourEvent, ExitWaitHandle});
Checkpoint();

// other stuff here

// check if thread must die
Checkpoint();
}
catch(ApplicationTerminatingException)
{
// thread must die, do cleanup and finalization stuff here
}
catch(Exception)
{
// holy cow! what should we do?
}
}

private void CheckPoint()
{
// fast check if the exit handle is set
if(ExitWaitHandle.WaitOne(0))
{
throw new ApplicationTerminatingException(); // custom exception
}
}

唯一的开销是在“一些”代码之后你需要设置一个检查点以中止你的线程。希望这就是您要找的。

关于c# - 由于 AutoResetEvent 信号处于 WaitOne 状态,线程在应用程序终止后仍然存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6631199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com