绑定StringProperty时出现多线程错误 [英] Multi-Threading error when binding a StringProperty

查看:66
本文介绍了绑定StringProperty时出现多线程错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于多线程和StringProperty绑定的问题。

I have a question about multi-threading and the binding of a StringProperty.

我有一个类 CacheManager ,包含 Thread ,它使用服务器上的更改更新我的缓存。现在,我想通知文本和进度百分比(这是一个标签 ProgressBar JavaFX的)。我为此使用公共静态 DoubleProperty StringProperty ,它们在 CacheManager中定义 class。我只是像这样绑定它:

I have a class CacheManager, which contains a Thread which updates my cache with the changes on the server. Now, I want to notify the user with a text and percentage of the progress (which are a Label and ProgressBar in JavaFX). I use public static DoubleProperty and StringProperty for this, which are defined in the CacheManager class. I just bind it like this:

progressBar.progressProperty().bind(CacheManager.progress);
someLabel.textProperty().bind(CacheManager.status);

现在,在Updater线程中,我更新了这些属性。使用 DoubleProperty 这很好用, ProgressBar 正在完美地显示进度。但是,使用状态(来自 StringProperty 的文本)更新 Label 会引发错误: java.lang.IllegalStateException:不在FX应用程序线程上; currentThread = Thread-9

Now, in the Updater thread, I update these Properties. With DoubleProperty this works just fine, and the ProgressBar is showing the progress perfectly. However, updating the Label with the status (which is the text from the StringProperty) throws an error: java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-9

现在,我的问题是:为什么 DoubleProperty 工作正常,而 StringProperty 会引发错误?他们考虑多线程有什么区别?

Now, my question is: Why does the DoubleProperty work just fine, while the StringProperty throws an error? What is the difference between them considering multi-threading?

任何有关重新设计的想法也欢迎,非常感谢任何帮助!

Any ideas on a redesign are also welcome and any help is greatly appreciated!

推荐答案

调用导致从FX应用程序线程以外的线程更改UI的代码是错误的,无论是否或不会抛出异常。如果您违反此规则,FX工具包会尽最大努力抛出异常,但在某些情况下,对性能的影响太大而无法执行检查。如果您创建了这些绑定,则必须在FX应用程序线程上执行对绑定到的属性的任何后续更改。即,如果您在后台线程中运行,则必须使用以下代码更改属性:

It is wrong to call code that results in changes to the UI from a thread other than the FX Application Thread, regardless of whether or not it throws an exception. The FX toolkit makes a best effort to throw an exception if you violate this rule, but in some cases the effect on performance is too great to perform the check. If you create these bindings, then any subsequent changes to the properties to which you have bound must be executed on the FX Application Thread. I.e., if you are running in a background thread, you must change the properties with code like:

Platform.runLater(() -> CacheManager.progress.set(...));

Platform.runLater(() -> CacheManager.status.set(...));

因为您可能不希望将服务代码绑定到JavaFX(通过 Platform class),您可以考虑使用侦听器而不是绑定,并从侦听器安排更新:

Since you probably don't want your service code to be tied to JavaFX (via the Platform class), you could consider using listeners instead of bindings, and scheduling the updates from the listeners:

CacheManager.progress.addListener((obs, oldValue, newValue) -> 
    Platform.runLater(() -> progressBar.setProgress(newValue.doubleValue())));
CacheManager.status.addListener((obs, oldStatus, newStatus) -> 
    Platform.runLater(() -> someLabel.setText(newStatus)));

如果用这些侦听器替换绑定,则可以自由更新任何线程上的属性。

If you replace the bindings with these listeners, then you are free to update the properties on any thread.

这篇关于绑定StringProperty时出现多线程错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆