为什么BackgroundWorker会抛出异常,而我的普通线程解决方案却没有?

时间:2011-05-20 23:05:12

标签: c# .net multithreading

我们希望避免在我们的UI上对可能密集的数据库调用没有反应。我一直在尝试不同的方法来达到以下场景。

  1. 用户调用该功能。
  2. 分叉执行功能的线程。
  3. 用户可以选择取消功能。
  4. 一个。如果用户没有取消,则该线程使用独立数据并生成其他一些不相关的UI。
  5. 湾如果用户确实取消,取消线程的处理并取消任何相关活动(例如我们将调用的SQL存储过程 - 与此问题无关)。
  6. 我自己是一个低级别的C ++人,我首先尝试了一个直接的Thread解决方案。然后,我尝试了解.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;
        }
    

    ...奇怪的

    • 调用该方法时,我的普通Thread解决方案正常工作。
    • 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);
    

2 个答案:

答案 0 :(得分:1)

正如人们已经发现的那样,很明显你会遇到Stackoverflow,线程与否 - 只是在单线程的情况下我怀疑CLR能够进行尾调优化。

如果您想模拟阻塞线程,请执行以下操作:阻止它。

Thread.Sleep(TimeSpan.FromSeconds(5));

答案 1 :(得分:0)

在没有看到所有代码的情况下,很难确定,但我几乎可以肯定你的SimulateSuperLongQuery代码无论如何都会导致StackOverflowException。它永远地递归地称呼自己(或者试图,无论如何)。

您的普通线程解决方案需要多长时间才能运行?如果你没有在那个版本中看到异常,它可能会被某个地方吞没。