2

My program listens to 3 types of events: ADD, DELETE, REFRESH which is triggered by a 3rd party library component on UI. My listener looks like this:

//the timestamp is the time when the event occurs
public void listenToEvent(Event event, long timestamp){
     if(event.getName().equals("ADD")){
           //handle ADD event

     }else if(event.getName().equals("DELETE")){
          //handle DELETE event

    }else if(event.getName().equals("REFRESH")){
          //handle REFRESH event

    }

}

The code works fine for each event, except a little problem with REFRESH event:

when refresh happened on UI, the 3rd party lib component fires consecutive 3 events in a short time, that's: ADD->DELETE->REFRESH, in this case my listener thinks there are 3 events, but actually it is only a refresh action on UI.

How can I optimise my code so that when ADD->DELETE->REFRESH happens consecutively very quickly, my listener could be smart enough to know it is only a REFRESH?

(ADD and DELETE events are NOT instances of the REFRESH event)

4

3 回答 3

2

正如我在评论中已经说过的,我在下面发布的这段代码正在运行(经过测试)。您可能需要对 REFRESH_TIMEOUT 进行一些调整,并可能使其成为线程安全的,但我已经测试了基本思想:

“如果ADD事件来了,为它创建一个定时器。当DELETE来的时候,检查是否已经有定时器任务。如果没有->处理DELETE。如果有->处理REFRESH。如果定时器到期->处理ADD”

这有点骇人听闻,但是根据您提供的信息,我认为此解决方案可能是最简单的方法。如果适当的事件来得更快,那么您可能会遇到问题,然后是您的 REFRESH_TIMEOUT。在这种情况下,逻辑会变得有点复杂。

long REFRESH_TIMEOUT=100;
Timer timer = null;
MyTask myTask = null;
public void listenToEvent(Event event, long timestamp){
    if(event.getName().equals("ADD")){
        timer = new Timer();
        timer.schedule(myTask = new MyTask(event), REFRESH_TIMEOUT);
    }
    if(event.getName().equals("DELETE")){
        if (myTask!=null && !myTask.expired){
            processRefresh(event);
            timer.cancel();
        }else{
            processDelete(event);
        }
    }
}

private static class MyTask extends TimerTask {
    Event event;
    boolean expired;
    public MyTask(Event event){
        this.event=event;
    }
    @Override
    public void run() {
        expired=true;
        processAdd(event);
    }
}

private void processAdd(Event e){
    ...
}
private void processDelete(Event e){
    ...
}
private void processRefrsh(Event e){
    ...
}
于 2013-09-19T08:32:23.960 回答
2

经过一番思考,我想出了自己的解决方案:

那是在 ADD & DELETE 条件下,我使用 Thread.sleep(1000),然后获取系统时间,然后在 REFRESH 条件下比较最新的系统时间,如果差异在 1 秒内,则为刷新事件。

private long timeout = 1000;
private long addEventTime;
private long deleteEventTime;
private long refreshEventTime;

public void listenToEvent(Event event, long timestamp){
     if(event.getName().equals("ADD")){
           Thread.sleep(timeout);
           addEventTime = System.currentTimeMillis();
           if((refreshEventTime - addEventTime) >timout){
               //handle ADD event
            }


     }else if(event.getName().equals("DELETE")){
           Thread.sleep(timeout);
           deleteEventTime = System.currentTimeMillis();
           if((refreshEventTime - deleteEventTime) >timout){
               //handle DELETE event
            }


    }else if(event.getName().equals("REFRESH")){
          refreshEventTime = System.currentTimeMillis();
          //handle REFRESH event

    }

}

任何大师对我的解决方案有任何评论吗?

于 2013-09-19T08:48:46.183 回答
0

如果事件 api 是经过深思熟虑的 imo,我认为 ADD 事件可能是 REFRESH 事件的一个实例。

这方面的一个例子是:

//AccidentAPI provided by FooBar Corp.
public CarAccidentEvent extends AccidentEvent {

    private String carMake;

    public String getMake() {
        return carMake;
    }
}

因此,您的听众将能够执行以下操作:

public void listenToAccidents(AccidentEvent e) {

    if (e instanceOf CarAccidentEvent) {
         doStuff();
    } else if (e instanceOf SkyJumpingEvent) {
         doOtherStuff();
    } else {
         blah();
    }
}

但同样,这是假设 ADD 和 DELETE 事件是 REFRESH 事件的实例。不过,也许他们的文档会进一步揭示有关 EventAPI 的信息,这可能有助于更好地解决问题。

否则,您可以为侦听器添加三个属性,用于以 Millis 为单位的系统时间,如果以 Millis 为单位的时间差大于 1ms,则处理它,否则,转到 REFRESH 情况。

于 2013-09-19T08:10:09.357 回答