gpt4 book ai didi

java - 当后台服务执行密集型任务时,如何防止 GUI 延迟?

转载 作者:行者123 更新时间:2023-11-29 09:28:49 25 4
gpt4 key购买 nike

我正在用 JavaFX 编写一个应用程序,它偶尔需要加载大约 1,000,000 行(或可能更多)的大型 CSV 文件。

当用户单击按钮开始加载文件时,服务将启动以加载内容,同时显示进度/取消对话框。 Service 中的 call() 方法基本上是一个 while 循环,它在每次迭代时从 CSV 文件加载另一行。

问题是当我启动服务时,进度条(不确定样式)变得不稳定。拖动对话框也是不稳定和滞后的。

我在网络上搜索解决方案时运气不佳,但我找到的最接近的方法是在循环中放置一个 Thread.sleep(),让 GC 等其他东西有机会 catch 。

这个解决方案似乎减少/消除了卡顿,但它会增加很多加载数据的时间。我还猜测不同处理器的确切 sleep 时间会有所不同。

有什么方法可以动态计算出 sleep 时间/频率?或者调用一些方法来阻塞足够长的时间以保持 GUI 响应?

我的服务代码:

public class CSVLoadingService extends Service<List<ObservableList<DoubleProperty>>> {
private ObjectProperty<File> srcFile = new SimpleObjectProperty<>();
private IntegerProperty startIndex = new SimpleIntegerProperty(0);
private ObjectProperty<Character> csvDelimeter = new SimpleObjectProperty(CSVParser.DEFAULT_SEPARATOR);
private DoubleProperty invalidCSVReplacement = new SimpleDoubleProperty(0);
private ObjectProperty<Dialog> dialog = new SimpleObjectProperty<>(null);

@Override
protected Task<List<ObservableList<DoubleProperty>>> createTask() {
return new Task<List<ObservableList<DoubleProperty>>>() {
final ObjectProperty<File> _srcFile = srcFile;
final IntegerProperty _startIndex = startIndex;
final ObjectProperty<Character> _csvDelimeter = csvDelimeter;
final DoubleProperty _invalidCSVReplacement = invalidCSVReplacement;

@Override
protected ObservableList<ObservableList<DoubleProperty>> call() throws Exception {
if (_startIndex.getValue() < 0)
throw new IllegalArgumentException("Start index can't be negative.");
if (_srcFile.getValue() == null)
throw new IllegalStateException("File can't be null.");

final ObservableList<ObservableList<DoubleProperty>> result = FXCollections.observableArrayList();

// Read the data from the CSV file.
try (final CSVReader reader = new CSVReader(new BufferedReader(new FileReader(_srcFile.getValue())),
_csvDelimeter.getValue(),
CSVParser.DEFAULT_QUOTE_CHARACTER,
_startIndex.getValue()))
{
// Read first line.
String[] csvLine = reader.readNext();

// If there is actually data, then read the rest of it.
if (csvLine == null || csvLine.length == 0) {
result.clear();
} else {
// Create columns.
for (String value : csvLine) {
result.add(FXCollections.observableArrayList());
}

// Parse the CSV reads and add them to the columns.
int iteration = 0;
do {
int i = 0;
for (String value : csvLine) {
// Convert the string to a number and add it to the column.
try {
result.get(i).add(new SimpleDoubleProperty(Double.parseDouble(value)));
} catch (NumberFormatException|NullPointerException e) {
result.get(i).add(_invalidCSVReplacement);
}
}

iteration++;
} while (!isCancelled() && null != (csvLine = reader.readNext()));
}
}

return result;
}
};
}

@Override
protected void succeeded() {
super.succeeded();

if (dialog.getValue() != null) {
dialog.getValue().close();
}
}

@Override
protected void failed() {
super.failed();

if (dialog.getValue() != null) {
dialog.getValue().close();
}
}

最佳答案

这是使用线程优先级的典型场景。您希望 GUI 线程的优先级高于后台线程。

关于java - 当后台服务执行密集型任务时,如何防止 GUI 延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32555783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com