从 .NET 到 Mono - 敲击 WinForms 时发生崩溃

发布于 2024-11-02 02:22:55 字数 1316 浏览 0 评论 0原文

几年前,我使用 C# 和 Visual Studio.net 在 .NET 1.1 上编写了这个轮盘应用程序:http://www.lonniebest.com/Roulette/

自 2007 年 4 月以来,我一直使用Ubuntu Linux 专用,所以今天我尝试使用 MonoDevelop IDE 重新编译旧代码。令我惊讶的是,代码构建得很好,没有错误,并且我能够运行这个 Windows 窗体 应用程序在Ubuntu上。

一切都运行良好(一开始),当我一次旋转轮盘赌轮时。如果我让它连续旋转 10 次,它甚至会运行得很好。然而,比这高得多(连续),应用程序崩溃了,我在 MonoDevelop 的“应用程序输出”窗格中看到的是:(

The application was terminated by a signal: SIGHUP

在 Visual Studio 中,我希望它能引导我找到代码中未处理的异常,但 MonoDevelop 似乎只在“应用程序输出”窗格中显示上述输出。)

这个应用程序确实锤炼了 Windows 窗体,它在每次旋转时一遍又一遍地更新大量表单元素,尽可能快地呈现。如果您在我在上面的链接中发布的 .NET 版本上运行它,您将看到它每秒更新所有这些表单元素 100 多次。这可能不是必需的,但整个应用程序也不是必需的,这就是我打算做的。

这些应用程序使用 Visual Studio 编译并在 Windows .NET 上运行,可以进行数百万次旋转而不会崩溃。

那么,什么可以让我让这段代码在 Mono/Linux 中更具弹性,鉴于上面的“SIGHUP”崩溃?

我已将 MonoDevelop 解决方案附加到此错误报告中: https://bugzilla.novell.com/show_bug.cgi?id=688014

Several years ago, I wrote this Roulette application on .NET 1.1 using C# and Visual Studio.net: http://www.lonniebest.com/Roulette/

Since April of 2007, I've been using Ubuntu Linux exclusively, so today I tried to recompile that old code using the MonoDevelop IDE. To my amazement, the code built fine without errors, and I was able to run this Windows Forms application on Ubuntu.

Everything worked fine (at first), when I would spin the roulette wheel one spin at a time. It would even run fine if I told it to spin it 10 times in a row. However, too much higher (in a row) than that, the applications crashes and all I see in the MonoDevelop's "Application Output" pane is:

The application was terminated by a signal: SIGHUP

(In Visual Studio, I'd expect it to direct me to an unhandled exception in my code, but MonoDevelop only seems to display the above output in the "Application Output" pane.)

This application really hammers Windows Forms, it updates numerous form element over and over again with each spin, as fast as can be rendered. If you run it on the .NET version I posted in the link above, you'll see it update all these form elements 100+ times a second. That may not be necessary, but neither is the application as a whole, and that's what I intend for it to do.

Compiled with Visual Studio, and running on Windows .NET, the applications can do millions of spins without ever crashing.

So, what might allow me to get this code more resilient in Mono/Linux, in light of the "SIGHUP" crash above?

I've attached the MonoDevelop Solution to this bug report:
https://bugzilla.novell.com/show_bug.cgi?id=688014

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泼猴你往哪里跑 2024-11-09 02:22:55

以下概念证明表明,这可能是对来自非非操作系统的 Windows 窗体 控件的混用使用用户界面线程。这个概念证明完全是脑残,因为我并不想找出 328 行 DisplayResults 函数中的哪些行是罪魁祸首。您可以使用下面的链接来缓解您的情况。

请阅读此处的背景信息:

以下补丁完全消除了我的症状。

diff --git a/Roulette/Roulette.cs b/Roulette/Roulette.cs
index d5ede34..ae098ac 100644
--- a/Roulette/Roulette.cs
+++ b/Roulette/Roulette.cs
@@ -402,6 +402,7 @@ namespace Roulette
                        //
                        // TODO: Add any constructor code after InitializeComponent call
                        //
+                       Application.Idle += (sender, e) => DisplayResultsEx();
                }

                /// <summary>
@@ -5135,6 +5136,11 @@ namespace Roulette

                public void DisplayResults()
                {
+
+               }
+
+               private void DisplayResultsEx()
+               {
                        //Display the current result.
                        lblCurrentResult.Text = m_Wheel1.CurrentResult.Name;

The following proof of concept shows that this is probably promiscuous use of Windows Forms controls from a non-UI thread. This proof of concept is completely braindead, because I didn't exactly want to find out what lines in your 328-line DisplayResults function were the culprit. You can use the links below to alleviate your situation.

Read on the backgrounds here:

The following patch completely removes the symptoms for me.

diff --git a/Roulette/Roulette.cs b/Roulette/Roulette.cs
index d5ede34..ae098ac 100644
--- a/Roulette/Roulette.cs
+++ b/Roulette/Roulette.cs
@@ -402,6 +402,7 @@ namespace Roulette
                        //
                        // TODO: Add any constructor code after InitializeComponent call
                        //
+                       Application.Idle += (sender, e) => DisplayResultsEx();
                }

                /// <summary>
@@ -5135,6 +5136,11 @@ namespace Roulette

                public void DisplayResults()
                {
+
+               }
+
+               private void DisplayResultsEx()
+               {
                        //Display the current result.
                        lblCurrentResult.Text = m_Wheel1.CurrentResult.Name;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文