1

在我的 Eclipse 插件中,我有一个TableViewer显示一些数据的插件。这些数据是从远程 REST 服务中检索的。因此,检索所有项目需要几秒钟的时间。这就是为什么我想在检索到它们后立即将它们添加到TableViewer's中。ContentProvider我在一个单独的线程中执行我的 REST 查询:

Thread retrieveThread = new RetrieveThread();
retrieveThread.run();

在这个线程中,我将项目添加到我的TableViewer

MyView.instance.addItems(items);

和类中的相同方法MyView

public void addItems(List<Result> items) {
    ModelProvider.INSTANCE.addItems(items);
    resultLabel.setText(ModelProvider.INSTANCE.getItems().size() + " items");
    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

        @Override
        public void run() {
            viewer.refresh();
        }
    });
}

我预计此过程会将项目添加到我TableViewer的然后刷新视图。但是现在发生的是我的 Eclipse 冻结并同时添加了所有这些项目。我怎样才能以更具响应性的方式做到这一点?

4

1 回答 1

2

问题是您run直接调用线程的方法。这不会产生一个新线程,它只是在线调用 run 方法。retrieveThread.start()会给你你正在寻找的行为。

但是,有一种更好的方法(至少更“对 eclipse 友好”),那就是使用 EclipseJob而不是 raw Thread.

    Job retrieveJob = new Job("Retrieving Data") 
    {           
        @Override
        protected IStatus run(IProgressMonitor monitor) {
            // do your REST call
            ModelProvider.INSTANCE.addItems(items);
            // if something goes wrong - don't return ok, obviously 
            return Status.OK_STATUS;                
        }
    };
    retrieveJob.addJobChangeListener(new JobChangeAdapter() {

        @Override
        public void done(IJobChangeEvent event) {
            if(event.getResult().isOK())
            {
                resultLabel.setText(ModelProvider.INSTANCE.getItems().size() + " items");
                viewer.refresh();
            }
        }           
    });
    // this will run in a background thread 
    // and nicely integrate with the UI
    retrieveJob.schedule(); 
于 2012-05-12T18:35:12.650 回答