对当前UI界面卡顿的问题,采用异步非阻塞调用UI的方式

需要返回值的情况

例如:通讯比较耗时,应将通讯部分的内容,加入到非UI线程中,可以使用Job创建。这样就不会造成UI界面整个卡顿了。

@Override
public void run() {
    TestFile testFile = (TestFile) model.getTestFileRootModel();
    String ip = testFile.getCorbaData().getIp();
    int port = testFile.getCorbaData().getPort();
    String name = testFile.getCorbaData().getName();
    String id = TestCaseUtils.getCorbaId(ip, port, name);
    TestReporter.writeBlueMessage(testFile, String.format(WideModelMessages.ConnectingInfo, id));
    // 采用非阻塞线程处理长时间任务。
    CompletableFuture<Object> future = new CompletableFuture<>();
    Job job = new Job(StringUtils.formatString("连接%s...", id)) {
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            // 异步进行连接。
            try {
                Object mdm = TestCaseUtils.getCorbaData(id);
                future.complete(mdm);
                return Status.OK_STATUS;
            } catch (Exception e) {
                future.completeExceptionally(e);
                return Status.CANCEL_STATUS;
            }
        }
    };
    job.schedule();
    future.whenComplete((mdm, e) -> {
        // 当完成后,重新调用UI线程进行相应UI操作。
        Display.getDefault().syncExec(() -> {
            if (e != null) {
                TestReporter.writeErrMessage(testFile, e.getLocalizedMessage());
                return;
            }
            // 由于我们需要在获取到对象之后,才能进行下一步操作。
            if (mdm == null) {
                TestReporter.writeErrMessage(testFile, String.format(WideModelMessages.NotGetCorba_Exception, id));
            } else {
                TestReporter.writeBlueMessage(testFile, String.format(WideModelMessages.SuccessConnect_Info, id));
            }
        });
    });
 
}

上面代码块中,TestCaseUtils.getCorbaData(id)方法非常耗时,将该部分放置在一个非UI的Job中处理。

dealReceive用于当接收到数据后,对UI界面进行刷新操作,通过传入的display.asyncExec方法执行刷新操作。

不需要返回值的情况

如果不需要返回对象,则无需使用future进行处理,如下所示:

/**
     * 异步非阻塞形式处理相应的UI线程。
     */
    public static void startAsyncUDPReceive(Display display, String jobName, int port, int bufLength, int timeout,
            BiConsumer<Display, String> uiConsumer) {
        // 采用非阻塞线程处理长时间任务。
        Job job = new Job(jobName) {
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                try {
                    UDPUtils.startLongReceive(port, bufLength, timeout, value -> {
                        display.syncExec(() -> {
                            if (value == null) {
                                return;
                            }
                            if (uiConsumer != null) {
                                uiConsumer.accept(display, value);
                            }
                        });
                    });
                    return Status.OK_STATUS;
                } catch (IOException e) {
                    LogUtils.severe(e.getLocalizedMessage());
                    return Status.CANCEL_STATUS;
                }
            }
        };
        job.schedule();
    }

此处UDPUtils用于持续监听某个端口,为一个阻塞的死循环,value(将UDP接收到的数据转换的字符串)每一次循环不一样,直接通过uiConsumer即用户的业务方法处理即可,不需要相应返回值对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值