从线程更新进度条时,SWT 窗口变得无响应

问题描述 投票:0回答:2

我正在编写一个 java swt 应用程序来处理服务器日志文件并生成带有一些分析的 Excel 工作表,我这样做没有任何问题。

当我尝试更新进度条时出现问题。

这是代码的基本流程。用户使用目录对话框选择日志文件并按下开始按钮。单击按钮时,将执行以下代码。

startButton.addMouseListener(new MouseAdapter() {
        public void mouseUp(MouseEvent e) {
            pm.setUserData(ud,progressBar);
            progressBar.getDisplay().asyncExec(new Runnable() {
                        @Override
                        public void run() {
                            pm.startProcessing();
                        }
                    });
}

在实际处理文件的类中,有一个简单的 while 循环,一直循环到到达文件末尾。从文件中读取每一行后,我调用一个更新进度条的方法。

while ((logEntry = br.readLine()) != null) {
                readSize += logEntry.length() + 1;
                //some long processing logic
                progressBar.setSelection(getProgress());
}

getProgress() 是一个计算文件读取百分比的简单方法

(read/total)*100

上面的程序正在运行。我得到了预期的结果。进度条更新,但 GUI 变得无响应。我无法移动窗户。我无法点击关闭按钮。

我尝试使用 Swing Worker 和 display.asyncExec()

java multithreading swt
2个回答
3
投票

SWT 文档明确指出

ProgressBar.setSelection()
当未从 UI 线程调用时,将抛出异常 (
ERROR_THREAD_INVALID_ACCESS
)。这意味着您要么在代码中的某个地方吞下异常,要么上面的代码在 UI 线程中运行。

有一个 片段展示了如何从线程更新

ProgressBar
:

display.asyncExec(new Runnable() {
                    @Override
                    public void run() {
                        if (bar.isDisposed ())
                            return;
                        bar.setSelection(getProgress);
                    }
                });

0
投票

我用不同的实现来解决相同的问题或想法,使用执行器服务,非常基本并且可以控制。

ScheduledExecutorService timer =
 Executors.newSingleThreadScheduledExecutor();
Runnable work = new Runnable() {
    public void run() {
        try {

            int currentPercent = externalAsyncService.getCurrentPercentReport();
            display.asyncExec(() - > progressBarReportStatus.setSelection(currentPercent));

            if (currentPercent >= 100) {
                timer.shutdown();
            }
        } catch (Exception e) {
            LOG.error(e.toString());
        }
    }
};
timer.scheduleAtFixedRate(work, 1, 5, TimeUnit.SECONDS);
© www.soinside.com 2019 - 2024. All rights reserved.