Vaadin按钮单击不会立即执行

时间:2018-08-14 10:34:31

标签: java vaadin vaadin7

我的页面带有过滤器表单,一些按钮和大网格。我可以根据过滤器形式搜索数据,并在网格中显示数据。搜索数据提供了线程,可能需要花费数秒至数分钟的时间。当我想单击按钮停止搜索(基本上是停止线程)时,操作总是在线程完成之后执行。但是我需要在线程工作时执行click事件。有人知道该怎么做吗? :)

UI具有@Push(PushMode.MANUAL),并且推送工作正常

简化代码:

@SpringComponent
@UIScope
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DistraintSearchComponent extends CustomComponent {

    @Autowired
    private Service service
    private Button searchButton = new Button("Search");
    private Button stopButton = new Button("Stop");
    private Thread searchThread;

    public void init(){

        searchButton.addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                searchThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        List<Results> results = service.findByFilter(filter); //this can take some time
                        refreshGrid(results);
                        getUI().push();
                    }
                });
                searchThread.start();
            }
        });

        stopButton.addClickListener(new ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                searchThread.interrupt();
            }
        });

    }
}

谢谢

1 个答案:

答案 0 :(得分:2)

searchThread.interrupt()不会在没有线程合作的情况下停止线程。从documentation我们可以看到它的作用:

  

如果在调用Object类的wait(),wait(long)或wait(long,int)方法或join(),join(long),join(long)时阻塞了此线程,int),sleep(long)或sleep(long,int)这类方法,则其中断状态将被清除,并且将收到InterruptedException。

     

如果此线程在可中断通道上被I / O操作阻塞,则该通道将关闭,该线程的中断状态将被设置,并且该线程将收到ClosedByInterruptException。

     

如果该线程在选择器中被阻塞,则该线程的中断状态将被设置,并且它将立即从选择操作中返回,可能具有非零值,就像调用选择器的唤醒方法一样。

     

如果以上条件均不成立,则将设置此线程的中断状态。

原因是您无法在任何地方停止执行,这将是很多未定义的行为。相反,您应该以受控方式停止线程。

因此,在您的搜索线程中(就您而言,它可能位于service.findByFilter(filter);内),您应该反复检查线程是否应结束:

 while (!Thread.currentThread().isInterrupted()) {
 // fetch another entry
}

文档还说您可以收到InterruptedExceptionClosedByInterruptException,因此在处理此异常时可以停止处理。 ClosedByInterruptExceptionIOException,因此这两个异常都是经过检查的异常,无论如何都必须处理它们,但是也许您不调用任何会引发此类异常的东西。

try {
    Thread.currentThread().sleep(123);
} catch (InterruptedException e) {
    return; // return from service.findByFilter(filter);
}