需要返回值的情况
例如:通讯比较耗时,应将通讯部分的内容,加入到非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即用户的业务方法处理即可,不需要相应返回值对象。