【问题标题】:StackOverflowException in multi-threaded UI update application多线程 UI 更新应用程序中的 StackOverflowException
【发布时间】:2017-07-25 20:18:32
【问题描述】:

我有一个应用程序,其中一堆工作正在停止工作(等待 Task.WhenAll...)并更新表单的进度部分。

我注意到,当它运行得特别快时(例如,当没有太多处理要做时,只需检查),我会抛出以下异常:

InvokeRequired 辅助方法是我不久前在这个网站上找到的,它看起来像这样:

    internal static void InvokeIfRequired<T>(this T control, Action<T> action)
        where T : ISynchronizeInvoke
    {
        if (control.InvokeRequired)
        {
            control.Invoke(new Action(() => action(control)), null);
        }
        else
        {
            action(control);
        }
    }

谁能告诉我为什么像这样分配标签文本值会导致 StackOverflowException?

编辑:这是异常的详细信息

【问题讨论】:

  • 也许当你分配新值时,它会执行一些事件,它会执行UpdateProgress...只需一步一步调试它,它就会告诉你哪里出了问题。
  • 如果您在其中设置断点并逐步执行,您应该能够看到正在循环的确切路径,从而导致堆栈溢出。这应该可以让您准确了解递归发生的原因......
  • 这在我的开发机器上永远不会发生 - 这是在它部署到的服务器上捕获的(包括符号以查看发生了什么)。我可以进行大量日志记录,但只是想知道在完成该过程之前是否有任何事情对任何人来说都很突出。
  • @StanleyGoosebump:那截图在哪里?您看起来好像有一个 VS 在它出错的地方中断,这表明您应该能够查看那个时候的堆栈跟踪,等等......
  • 你为什么不看看堆栈跟踪。您应该能够非常非常快速地看到溢出。

标签: c# multithreading winforms


【解决方案1】:

可能有两种情况:

  • 您从工作流中收到太多更新信息的请求,这会破坏应用程序 - 在这种情况下,您需要执行一些称为“去抖动”的操作 - 当您收到请求时,您不会执行更新,而只会执行更新将计时器设置为 200 毫秒并取消前一个计时器,计时器执行更新,这样您就可以确保更新不会比 200 毫秒内更频繁地发生,这不会破坏应用程序。如果您在很长一段时间内经常在不到 200 毫秒的时间内收到新请求,则可能会比这更复杂,那么您需要实现有时更新而不触发计时器的逻辑。
  • 您有一些循环引用导致代码多次执行(但如果是这种情况,您可能总是会遇到异常) - 您只能通过使用调试器并检查调用有问题代码的堆栈来检查这一点.

【讨论】:

  • 谢谢 Ivan - 你的第一点让我思考 - 这个错误只在系统执行检查而不是实际处理工作时出现。计时器不是一个选项,但我添加了一个内部计数器,它限制直到达到特定的处理点。现在又恢复正常了 - 非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2013-08-02
  • 2015-10-26
  • 2011-11-09
  • 1970-01-01
  • 2014-08-26
相关资源
最近更新 更多