开源改变世界!!

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129

推推 grbl 2年前 (2023-01-26) 126次浏览
关闭
zamfi 打开了这个问题 2014 年 2 月 17 日 · 7条评论
关闭

控制台从外部 UI 线程更新,导致某些平台出现死锁。#129

zamfi 打开了这个问题 2014 年 2 月 17 日 · 7条评论

注释

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129

在 MainWindow.messageForConsole 中,更新了 consoleTextArea。该方法在 RXTX 线程中被调用,但它应该在 AWT 事件线程中运行。在某些平台上,这会导致 AWT 线程中的死锁,从而导致程序冻结。(我运行的是 OS X 10.9,我经常遇到死锁。)

我通过修改 MainWindow.messageForConsole 为自己解决了这个问题,如下所示

@Override
public void messageForConsole(final String msg, final Boolean verbose) {
    final javax.swing.JTextArea consoleTextArea = this.consoleTextArea;
    final javax.swing.JCheckBox showVerboseOutputCheckBox = this.showVerboseOutputCheckBox;
    final javax.swing.JCheckBox scrollWindowCheckBox = this.scrollWindowCheckBox;

    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            if (!verbose || showVerboseOutputCheckBox.isSelected()) {
                consoleTextArea.append((verbose ? "[verbose]" : "") + msg);

                if (consoleTextArea.isVisible() &&
                        scrollWindowCheckBox.isEnabled()) {
                    consoleTextArea.setCaretPosition(consoleTextArea.getDocument().getLength());
                }                    
            }
        }
    });
}

我不确定这是一个理想的解决方案,而且我不确定是否还有其他地方可以从 AWT 事件线程外部更新 swing 元素。

如果有帮助,我很乐意四处寻找并提交拉取请求。

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
所有者

JTextArea 附加函数应该是线程安全的,可能是 setCaretPosition 调用导致了问题。请发送拉取请求,我会添加更改。

可能还有其他一些地方应该像这样移到 AWT 事件线程之外。如果您确实最终寻找,您可能会找到一些东西。

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
作者

嗯,Swing 文档表明整个包都不是线程安全的,而且我在 javadoc 中没有发现任何针对 JTextArea.append 的异常。

无论如何,我会尽快发送拉取请求。

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
所有者

哦,这很有趣。http://stackoverflow.com/questions/8436949/thread-safety-of-jtextarea-append

Append 在 Java 7 中显然不再是线程安全的,最近更新了 UGS 以供使用。

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
作者

很有意思。Mac 从未附带 Java 7,但我确实自己安装了它。这或许可以解释为什么搜索其他有相同问题的人收效甚微!

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
贡献者

我是 Java UI 框架的新手。在这种情况下,项目是否遵循特定的设计模式(MVP/MVC/MVVM/WTFBBQ)?它看起来像 uielements 下的一些组件,充当演示者/视图模型以将视图与模型分离,但覆盖范围似乎是零碎的。对话框似乎被表示,命令表也是如此,但它看起来不像主窗口的其余部分被表示。

这不是对 Zamfi 修复的评论,因为无论模式如何,都需要逻辑。我认为完善 UI 的演示者/视图模型集将阐明应如何实现 UI 更新。在进行估算工作时,我对直接更新文本字段中的值感到很奇怪;我有一种挥之不去的感觉,我应该在 UI 线程中做这件事。我与现有代码保持一致,但遇到了与 UI 在事件处理程序方法完成之前不更新这一事实相关的问题。(例如,我更新了行数并将估计的运行时间设置为“估计…”,但必须启动一个线程来运行模拟,以便当前方法可以完成,并且显示行和“估计”值,同时模拟正在运行。)

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
所有者

@michmerr你在这里几乎所有的帐户都是正确的。MainWindow.java 是一种垃圾场。基本上提醒一下,这个项目是作为 GcodeSender 的跨平台端口开始的,代码几乎是逐字复制的。

随着它们变得越来越复杂,我逐渐将它们拉出来,比如控制器和通信层,以及一些我想定制的 ui 组件。我的宏伟愿景是将 UGS 变成一个独立的库,任何人都可以在新的前端中使用。即使现在前端可以很容易地分叉,我在代码中的某个地方有一个用于 UGS CLI 的小型概念验证项目。

控制台从外部 UI 线程更新,导致某些平台出现死锁。 #129
所有者

已通过拉取请求#134修复