首先, Thread.Abort() 是邪恶的——明白了!现在让我解释一下我的情况...
情况:
我有一个只向用户显示当前运行状态的仪表板。它针对 Sql Server DB 执行各种选择查询,并执行一些最终在仪表板上显示给用户的计算。用户可以同时打开多个仪表板。我有一个计时器线程,每隔几秒钟刷新一次仪表板。该计时器线程产生另一个线程(实际上队列在线程池上工作)以执行长时间运行的计算/查询。
问题:
当用户点击 X 关闭 Dashboard 窗口时,它需要立即关闭(比如说在一秒钟内,我认为 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,有时则不会。我发现在执行查询的过程中它几乎没有被捕获。
[更新]我最近发现如果我检查内部异常,我可以捕获 ThreadAbortException。
问题:
- 在这种情况下可以使用 Thread.Abort() 吗?如果是这样,我如何始终捕获 ThreadAbortException 以便用户在关闭表单时看不到它?(根据我的阅读,我认为这是不可能的)
- 如果不能使用 Thread.Abort() (这是我认为你们大多数人会回答的),那么这是我对使用“全局布尔标志”来告诉线程何时关闭的其他担忧。
- 我担心线程不会在 1 秒的时间限制内停止。(例如,我可能有一些查询需要 1-2 秒才能运行)
- 我将不得不用 if(shouldShutdown) 语句来弄乱我的代码。
- 我应该将 shouldShutdown 标志设为静态,以便我的所有课程都可以使用它吗?如果用户可以同时打开多个仪表板,这会带来问题吗?(我担心在所有仪表板之间共享静态变量。这是我绝对不想要的。)
- 当工作线程看到他们必须关闭时,他们应该抛出异常还是直接返回?如果它们只是返回,那么我将不得不添加更多 if(shouldShutdown) 检查,因为某些函数返回 false 是可以的。如果抛出异常是可以的,你推荐哪个异常?定制的?
谢谢