【问题标题】:Why not run long tasks on the EDT if I want them to be blocking如果我希望它们被阻塞,为什么不在 EDT 上运行长任务
【发布时间】:2016-06-08 21:09:36
【问题描述】:

我知道在 Java 中有诸如 Swing worker 之类的类用于处理需要很长时间的事情,因此不会阻塞 EDT(事件调度线程)。但为什么不呢?

我有一个应用程序,并且正在执行的每个用户操作都应该是一个阻止操作。那么在这种情况下,我有什么理由不应该在 EDT 线程上运行?

例如。如果用户单击加载和处理电子表格的项目。然后我不希望用户在处理完成之前进入下一步。我不应该在 EDT 上这样做以确保事件的“顺序”。

我错过了什么?

【问题讨论】:

    标签: java


    【解决方案1】:

    您只会与 Java GUI 应用程序的非常基本/常见的设计理念相矛盾。

    如果您希望您的用户“等待”,例如,您可以设置模态窗口,这根本不允许他点击其他任何地方的任何按钮。这样做......仍然允许更新您的 GUI 中的其他元素(例如,如果您在某处有一些“状态栏”)。

    换句话说:是的,在 EDT 上做任何事情都非常容易,而且作为“简单的设计”可能很诱人;但很有可能,在某些时候你会后悔这种“java标准/最佳实践”的偏差。如果发生这种情况……那么您将需要大量进行更改才能摆脱困境。

    最后,永远不要忘记 wtf-code-quality-metric;并接受以这种方式滥用 EDT 将保证您在评论中获得许多 WTF。

    【讨论】:

    • 谢谢。和“我喜欢 WTF 图形”。我面临的问题是,如果我显示一个模态对话框,那么它不会让我真正开始运行任务,因为它会阻塞所有内容。如果运行任务然后显示模态窗口,那么任务就没有完成。不知道如何
    • 虽然遵循最佳实践通常是一个很好的做法,但我还是提倡尝试了解其背后的原因,尤其是在您想要偏离的情况下。这样,您将能够做出更好的决定,并且如果您偏离最佳实践,您很可能有很好的理由。因此,我认为 OP 的问题实际上是一个很好的问题。 - 除此之外,您肯定会获得 +1,尤其是 WTF 指标 ;)
    • @Snake 我明白了。我认为这可能值得提出一个新问题 - 在其中明确指定要解决的潜在问题。
    • @Thomas 你说的很对;也许 Snake 会跟进并提出另一个问题让我们到达那里。
    • 我按照建议跟进了一个新问题。 stackoverflow.com/questions/37703633/…
    【解决方案2】:

    问题是阻止 EDT 也会阻止任何 UI 更新,因此您的 UI 可能看起来没有响应。在这种情况下,您通常会使用模态对话框,这会使 UI 仅在流程完成后接受进一步的用户输入。例如,这样做可以让您显示一些不确定的进度条(即“工作”动画) - 即用户不会感觉到应用程序不再响应。

    除了模式对话框之外还有其他选项(例如,使用玻璃窗格等),请看这里的示例:Creating a nice "LOADING..." animation

    【讨论】:

    • 特别是:如果用户在它周围拖动窗口可能无法正确重绘。
    • @user268396 是的,这是没有响应的 EDT 可能发生的最糟糕的事情之一。
    • 感谢您的建议,有趣的一个。并为此 +1
    【解决方案3】:

    让您的 UI 能够满足用户操作被认为是一种很好的做法。在您的情况下,对于长任务,通常会添加一个 Cancel 按钮,以便用户可以在他们认为有必要时取消该操作。

    可以在 EDT 上做所有事情,但我建议不要这样做。有些人倾向于将(完全)无响应的 UI 视为应用程序死亡的标志。

    在我看来,让某种 UI 组件向用户显示(冗长的)操作正在进行中是可行的方法。

    【讨论】:

    • 感谢您的评论。关于取消的好点,但在我的情况下没有取消选项(数据库更新和查询)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-20
    • 2012-04-05
    • 2020-11-16
    • 2019-04-20
    相关资源
    最近更新 更多