【问题标题】:What's causing my c# WinForms application to freeze / hang? [closed]是什么导致我的 c# WinForms 应用程序冻结/挂起? [关闭]
【发布时间】:2011-01-19 15:54:57
【问题描述】:

我有一个 .Net 2.0 C# WinForms 应用程序,它在开发中运行良好,但在生产中偶尔会冻结。我已经找到了所有常见的罪魁祸首:
1. 我使用 InvokeRequired 和 Invoke 来确保没有 UI 组件是从错误的线程操作的。
2. 我已经在 UI 线程上同步了我的所有计时器对象。
3. 我已经阅读了这篇关于 OnUserPreferenceChanged 的​​文章http://www.ikriv.com/en/prog/info/dotnet/MysteriousHang.html,我确实遇到了这个问题,但我已经解决了。

当我们从 .Net 1.1 迁移到 .Net 2+ 时,这种情况就开始发生了。在此之前,它永远不会挂起。

当出现此问题并且主 UI 线程总是卡在某个新的随机位置时,我正在使用托管堆栈资源管理器定期从生产应用程序获取堆栈跟踪。如果这是线程死锁,它不会在 WaitOne 上被阻塞,正如您所期望的那样。

我的应用程序执行以下操作:
- 使用多个 System.Timers.Timer 实例。
- 使用 WMI 管理打印。
- 有一些后台线程可以对服务器进行 Web 服务调用,但不与 UI 交互。
- 有一些后台线程使用 System.Diagnostics.Process 来查看计算机上的其他进程,有时会杀死它们。
- 与第 3 方 dll 交互,该 dll 使用串行端口与票据接受者通信。
- 与一些 com/activex/ocx 控件交互以与信用卡读卡器交互。

以下是它一次挂起以及当时所有堆栈跟踪的示例:

Thread ID: 2816  
    0. System.Threading.WaitHandle.WaitOne (Source Unavailable)
    1. System.Threading.WaitHandle.WaitOne (Source Unavailable)
    2. System.Threading.WaitHandle.WaitOne (Source Unavailable)
    3. System.Management.MTAHelper.WorkerThread (Source Unavailable)
    4. System.Threading.ThreadHelper.ThreadStart_Context (Source Unavailable)
    5. System.Threading.ExecutionContext.Run (Source Unavailable)
    6. System.Threading.ThreadHelper.ThreadStart (Source Unavailable)

Thread ID: 2828  

Thread ID: 2852  
    0. MeiNet.EBDS.BillAcceptor.submitRequestStack (Source Unavailable)
    1. MeiNet.EBDS.BillAcceptor.OnHandleEscrowed (Source Unavailable)
    2. MeiNet.EBDS.BillAcceptor.EventHandler (Source Unavailable)

Thread ID: 2908  

Thread ID: 2820  
    0. System.Threading.Thread.Sleep (Source Unavailable)
    1. MyApp.ProcessKiller.startSpecialKillerLoop (ProcessKiller.cs:115)
    2. System.Threading.ThreadHelper.ThreadStart_Context (Source Unavailable)
    3. System.Threading.ExecutionContext.Run (Source Unavailable)
    4. System.Threading.ThreadHelper.ThreadStart (Source Unavailable)

Thread ID: 2600  

Thread ID: 2844  
    0. System.Threading.Thread.Start (Source Unavailable)
    1. System.Net.TimerThread.Prod (Source Unavailable)
    2. System.Net.TimerThread.TimerQueue.CreateTimer (Source Unavailable)
    3. System.Net.ServicePoint..ctor (Source Unavailable)
    4. System.Net.ServicePointManager.FindServicePointHelper (Source Unavailable)
    5. System.Net.ServicePointManager.FindServicePoint (Source Unavailable)
    6. System.Net.HttpWebRequest.FindServicePoint (Source Unavailable)
    7. System.Net.HttpWebRequest.GetRequestStream (Source Unavailable)
    8. System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke (Source Unavailable)
    9. MyApp.MyServer.Server.hb4 (Reference.cs:588)
    10. MyApp.HeartbeatSender.SendThreadedHeartbeat (HeartbeatSender.cs:81)
    11. MyApp.HeartbeatSender.StartHeartbeatLoop (HeartbeatSender.cs:40)
    12. System.Threading.ThreadHelper.ThreadStart_Context (Source Unavailable)
    13. System.Threading.ExecutionContext.Run (Source Unavailable)
    14. System.Threading.ThreadHelper.ThreadStart (Source Unavailable)

Thread ID: 2824  
    0. System.Threading.Thread.Sleep (Source Unavailable)
    1. MyApp.OfficeMonitor.StartMonitoring (OfficeMonitor.cs:84)
    2. System.Threading.ThreadHelper.ThreadStart_Context (Source Unavailable)
    3. System.Threading.ExecutionContext.Run (Source Unavailable)
    4. System.Threading.ThreadHelper.ThreadStart (Source Unavailable)

Thread ID: 2584  
    0. [Internal thisFrame, 'M-->U', System.Windows.Forms.UnsafeNativeMethods::GetModuleHandle] (Source Unavailable)
    1. System.Windows.Forms.Application.get_ComCtlSupportsVisualStyles (Source Unavailable)
    2. System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintWorker (Source Unavailable)
    3. System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintUp (Source Unavailable)
    4. System.Windows.Forms.ButtonInternal.ButtonStandardAdapter.PaintOver (Source Unavailable)
    5. System.Windows.Forms.ButtonInternal.ButtonBaseAdapter.Paint (Source Unavailable)
    6. System.Windows.Forms.ButtonBase.OnPaint (Source Unavailable)
    7. System.Windows.Forms.Control.PaintWithErrorHandling (Source Unavailable)
    8. System.Windows.Forms.Control.WmPaint (Source Unavailable)
    9. System.Windows.Forms.Control.WndProc (Source Unavailable)
    10. System.Windows.Forms.ButtonBase.WndProc (Source Unavailable)
    11. System.Windows.Forms.Button.WndProc (Source Unavailable)
    12. System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Source Unavailable)
    13. System.Windows.Forms.Control.ControlNativeWindow.WndProc (Source Unavailable)
    14. System.Windows.Forms.NativeWindow.Callback (Source Unavailable)
    15. [Internal thisFrame, 'M-->U', System.Windows.Forms.SafeNativeMethods::UpdateWindow] (Source Unavailable)
    16. System.Windows.Forms.Control.Update (Source Unavailable)
    17. System.Windows.Forms.Control.Refresh (Source Unavailable)
    18. MyApp.MainForm.ClearFields (MainForm.cs:4057)
    19. MyApp.MainForm.ShowHomeButtons (MainForm.cs:5664)
    20. MyApp.MainForm.ShowScreenSaver (MainForm.cs:4284)
    21. MyApp.MainForm.ScreensaverTimerTick (MainForm.cs:7817)
    22. System.RuntimeMethodHandle.InvokeMethodFast (Source Unavailable)
    23. System.Reflection.RuntimeMethodInfo.Invoke (Source Unavailable)
    24. System.Delegate.DynamicInvokeImpl (Source Unavailable)
    25. System.Windows.Forms.Control.InvokeMarshaledCallbackDo (Source Unavailable)
    26. System.Windows.Forms.Control.InvokeMarshaledCallbackHelper (Source Unavailable)
    27. System.Threading.ExecutionContext.runTryCode (Source Unavailable)
    28. System.Threading.ExecutionContext.RunInternal (Source Unavailable)
    29. System.Threading.ExecutionContext.Run (Source Unavailable)
    30. System.Windows.Forms.Control.InvokeMarshaledCallback (Source Unavailable)
    31. System.Windows.Forms.Control.InvokeMarshaledCallbacks (Source Unavailable)
    32. System.Windows.Forms.Control.WndProc (Source Unavailable)
    33. System.Windows.Forms.ScrollableControl.WndProc (Source Unavailable)
    34. System.Windows.Forms.ContainerControl.WndProc (Source Unavailable)
    35. System.Windows.Forms.Form.WndProc (Source Unavailable)
    36. System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Source Unavailable)
    37. System.Windows.Forms.Control.ControlNativeWindow.WndProc (Source Unavailable)
    38. System.Windows.Forms.NativeWindow.Callback (Source Unavailable)
    39. [Internal thisFrame, 'M-->U', System.Windows.Forms.UnsafeNativeMethods::DispatchMessageW] (Source Unavailable)
    40. System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop (Source Unavailable)
    41. System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner (Source Unavailable)
    42. System.Windows.Forms.Application.ThreadContext.RunMessageLoop (Source Unavailable)
    43. System.Windows.Forms.Application.Run (Source Unavailable)
    44. MyApp.MainForm.Main (MainForm.cs:2975)

对我应该做什么有什么建议吗?

【问题讨论】:

  • 挂起是指不再响应的用户界面吗?还是显示了一些错误信息?
  • @Nobody 我认为没有人可以在不查看所有代码的情况下就具体导致您的应用程序挂起的原因向您提供任何建议(这超出了 SO 的范围)。跨度>
  • 死锁不仅仅发生在您告诉某事等待时。如果您正在锁定某个东西,而另一个线程去锁定它,这可能会导致死锁,如果一个方法依赖于它尚未初始化的东西并且需要锁定它可能会导致死锁。等等等等等等。当你使用线程时要super小心。
  • 没有错误信息。用户界面变得无响应。
  • 我应该补充一点,这种挂起是在我们从 .Net 1.1 迁移到 .Net 2+ 之后开始发生的。在此之前从未发生过。

标签: c# multithreading winforms


【解决方案1】:

一些想法:

  • 您是否在开发环境中使用了生产环境中不存在的任何预处理器标志。所以任何#If Debug 或其他任何东西。

  • 您是否在发布模式的开发环境中进行了测试?还是不挂吗?

  • 机器有什么不同?一个是否有更多的 RAM,一个四核与双核,一个位于一百万个防火墙后面而另一个没有?

  • 在您的线程中,您确定在更新 UI 元素之前没有任何东西等待回调完成吗?

  • 您在使用数据库吗?如果是,它们是否不同?它们有何不同?

  • 挂起是否可能是由于您正在拉取 StackTraces 造成的?

  • 是否有任何你在任何地方吞下的异常情况可以告诉你正在发生的事情?

  • 机器上的串口有什么不同吗?

  • 是否使用相同的钞票接收器?

继续等等。

尝试在新的虚拟机上安装它,看看会发生什么。可能是一些旧的 dll 或驱动程序,大多数情况下Works on my machine 出现症状是因为你做了一些你忘记的事情使事情正常进行。

【讨论】:

  • 感谢您的建议。快速回答:没有标志,没有不同的模式,我会检查硬件,没有线程在等待回调,没有数据库,直到遇到这个问题才开始获取堆栈跟踪,记录所有异常,我会检查串口,我们'将检查接受者。再次感谢您考虑这个问题。
【解决方案2】:

我们遇到了完全相同的问题,这篇文章(就像您提到的那样)为我们指出了解决方案: http://www.ikriv.com/dev/dotnet/MysteriousHang.html#WhatToDo

我们使用了带有以下代码的启动画面:

ThreadPool.QueueUserWorkItem((x) =>
{
    using (var splashForm = new SplashForm())
    {
        splashForm.Show();
        while (!done)
            Application.DoEvents();
        splashForm.Close();
    }
});

我们很幸运能够重现僵局。我们有一台笔记本电脑/平板电脑,您可以在其中将屏幕与键盘分离,这样您就只有一台平板电脑。每次我们分离屏幕时,我们的应用程序都会挂起。消除飞溅后,我们的问题就消失了。

顺便说一下,我们从挂起的程序中得到了完全相同的堆栈跟踪:

System.Threading.WaitHandle.WaitOne (Source Unavailable)
1. System.Threading.WaitHandle.WaitOne (Source Unavailable)
2. System.Threading.WaitHandle.WaitOne (Source Unavailable)
3. System.Management.MTAHelper.WorkerThread (Source Unavailable)
4. System.Threading.ThreadHelper.ThreadStart_Context (Source Unavailable)
5. System.Threading.ExecutionContext.Run (Source Unavailable)
6. System.Threading.ThreadHelper.ThreadStart (Source Unavailable)

当然,我不知道您的问题是否有相同的原因/解决方案......但这为我们做到了。

【讨论】:

    【解决方案3】:

    我看到了类似的挂起,其中一个线程正在调用 Application.get_ComCtlSupportsVisualStyles 。

    我想知道您是否启用了视觉样式? http://ryanfarley.com/blog/archive/2004/05/05/599.aspx 描述了如何使用代码或清单文件进行操作。 (我认为清单文件是首选解决方案。)

    如果您启用了视觉样式,并且假设操作系统支持主题(我认为这个功能从 XP 开始),那么 Application.get_ComCtlSupportsVisualStyles 几乎不需要做那么多工作,并且可以快速返回 true。

    说了这么多,我还是不明白为什么调用 GetModuleHandle() 会挂起。我在网上找到的大部分内容表明这将是 LoadLibrary() 期间的问题,而不是 .NET Win Forms 绘制事件期间的问题。我不知道您是否有另一个线程同时在 LoadLibrary() 中进行不安全的工作...?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      相关资源
      最近更新 更多