.net 表单关闭时调用thread.Abort()可以吗?如果不是,那么全球旗帜是否足够好?
首先,Thread.Abort()是邪恶的-明白了!现在让我解释一下我的情况 情况: 我有一个只向用户显示当前运行状态的仪表板。它对Sql Server DB执行各种select查询,并执行一些计算,最终在仪表板上显示给用户。用户可以同时打开多个仪表板。我有一个计时器线程,每隔几秒钟刷新一次仪表板。该计时器线程生成另一个线程(实际上是对线程池中的工作进行排队)以执行长时间运行的计算/查询 问题: 当用户单击X关闭仪表板窗口时,它需要立即关闭(比如在一秒钟内,我认为2秒钟太长)。所以我使用这个代码:.net 表单关闭时调用thread.Abort()可以吗?如果不是,那么全球旗帜是否足够好?,.net,multithreading,threadabortexception,thread-abort,.net,Multithreading,Threadabortexception,Thread Abort,首先,Thread.Abort()是邪恶的-明白了!现在让我解释一下我的情况 情况: 我有一个只向用户显示当前运行状态的仪表板。它对Sql Server DB执行各种select查询,并执行一些计算,最终在仪表板上显示给用户。用户可以同时打开多个仪表板。我有一个计时器线程,每隔几秒钟刷新一次仪表板。该计时器线程生成另一个线程(实际上是对线程池中的工作进行排队)以执行长时间运行的计算/查询 问题: 当用户单击X关闭仪表板窗口时,它需要立即关闭(比如在一秒钟内,我认为2秒钟太长)。所以我使用这个代码
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_timerThread.Abort();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// we're on the timer thread now
try
{
RefreshUi();
}
catch (ThreadAbortException)
{
System.Threading.Thread.ResetAbort();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
问题是有时捕获到ThreadAbortException,有时则没有。我发现,在执行查询的过程中,这几乎是不起作用的。
[更新]我最近发现,如果检查innerexception,我可以捕获ThreadAbortException
问题:
- 我担心线程不会在1秒的时间限制内自行停止。(例如,我可能有一些查询需要1-2秒才能运行)
- 我将不得不用:if(shouldShutdown)语句来混乱我的代码
- 我是否应该将shouldShutdown标志设置为静态,以便我的所有类都可以使用它?如果用户可以同时打开多个仪表板,这会造成问题吗?(我担心静态变量会在所有仪表板上共享。这是我绝对不想要的。)
- 当工作线程看到它们必须关闭时,它们应该抛出异常还是返回?如果它们只是返回,那么我必须添加更多的If(shouldShutdown)检查,因为有些函数返回false是可以的。如果抛出异常是可以的,那么您建议使用哪种异常?定制的
谢谢正确的方法是
ManualResetEvent
并在关闭时从主线程触发AutoResetEvent
处理程序中的sql请求并正常退出线程您的捕获代码错误。您正在中止工作线程,而不是UI线程。我看不出立即关闭(关闭仪表板)如何连接到后台线程?在窗口关闭后,让他们使用
AutoResetEvent
优雅地结束。@Anri说得对。我假设由于表单创建了线程,它们必须先完成,然后才能关闭。但我猜你是说他们不必。1)你是说使用BeginInvoke()?我已经在做了。2) ManualResetEvents不适合暂停线程而不是终止线程吗?3) 你是怎么做到的?4) 你是说因为我已经在使用线程了,所以表单可以关闭而不用先终止线程吗?5) 如果仪表板关闭,进程/应用程序不会终止。1。我的意思是SqlCommand.BeginExecuteReader
或您用来获取数据的任何东西。2.执行异步sql查询时线程在做什么?右-正在等待,但仍在侦听来自控制线程的消息,该线程应停止等待并开始中止sql请求。对于其他情况(不是sql),它可以用于检查事件(设置/未设置)的状态,而无需等待。4.我是说FormClosing事件处理程序应该触发线程关闭过程,而不是等待它们完成。