为什么BackgroundWorker抛出异常,而我的纯线程解决方案却没有;t
本文关键字:解决方案 线程 抛出异常 BackgroundWorker 我的 为什么 | 更新日期: 2023-09-27 17:57:29
我们希望避免UI对潜在的密集型数据库调用没有响应。我一直在尝试不同的方法来达到以下场景。
- 用户调用该功能
- 执行功能的线程是分叉的
- 用户可以选择取消该功能
- a。如果用户不取消,线程将使用独立的数据并生成一些其他不相关的UI
- b。如果用户取消,则取消线程的处理并取消任何相关活动(例如我们将调用的SQL存储过程——与本问题无关)
作为一个低级的、C++类型的人,我首先尝试了一个直线程解决方案。然后,我尝试研究.NET的BackgroundWorker解决方案(C#)。
以下是我用来模拟线程要处理的潜在密集型操作的代码。
/// <summary>
/// Simulates the processing for a query that is pretty much
/// unresponsive after it's been invoked.
/// </summary>
public void SimulateSuperLongQuery ()
{
// Pass the time, for a very long time...
for (int i=0; i < int.MaxValue; i++)
SimulateSuperLongQuery();
_completed = true;
}
特别。。。
- 我的纯线程解决方案在调用该方法时运行良好
- BackgroundWorker解决方案在调用该方法时抛出StackOverflowException
有人知道BackgroundWorker为什么会导致异常吗
代码,以防有帮助。以下是一些BackgroundWorker代码。它直接来自MSDN网站。
BackgroundWorker bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
// ...
private void bw_DoWork (object sender, DoWorkEventArgs e)
{
QuerySimulator query = new QuerySimulator();
query.SimulateSuperLongQuery();
}
这是我的一些普通代码。
// Fire up a thread to run a query
QuerySimulator query = new QuerySimulator();
Thread queryThread = new Thread(query.SimulateSuperLongQuery);
正如人们已经发现的那样,很明显,无论是否有线程,您都会遇到Stackoverflow——只是在单线程的情况下,我怀疑CLR能够进行尾调用优化。
如果你想模拟阻塞线程,就这么做:阻塞它
Thread.Sleep(TimeSpan.FromSeconds(5));
在没有看到所有代码的情况下,很难确定,但我几乎可以肯定,无论发生什么,您的SimulateSuperLongQuery代码都会导致StackOverflowException。它在永远递归地调用自己(或者尝试这样做)。
您的纯线程解决方案需要多长时间才能运行?如果你没有在那个版本中看到一个例外,它可能只是在某个地方被吞噬了。