本文介绍了Guava EventBus延迟嵌套事件的处理程序执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与 Guava EventBus派发完全相同,但是尽管基本问题相似,但我的问题尝试修复已使我陷入黑暗.

My issue is pretty identical to Guava EventBus dispatching, but while the underlying issue is similar, my attempted fix has left me in the dark.

我有2个事件被背对背触发.完成所有处理程序后,第二个事件取决于第一个事件的最终状态.只有在第一个事件未取消的情况下,它才应触发.问题是这两个事件都是从另一个事件的处理程序中触发的.

I have 2 events that are fired back to back. The 2nd event is dependant on the final state of the first event after all handlers are done with it. It should only fire if the 1st event wasn't cancelled. The catch is that both of these events are fired from within another event's handler.

因此,尽管我不在乎谁听第一嵌套事件,但我确实在乎他们要说些什么.我已经离开了事件和Guava的EventBus旨在解决的问题空间了吗?

So while I don't care who listens to the 1st nested event, I do care what they have to say about it. Am I already leaving the problemspace that events and Guava's EventBus aim to solve?

考虑:

public void parentEventHandler(ParentEvent parentEvent) {
    Object nestedEvent = createNestedEvent();
    eventBus.post(nestedEvent);

    if(nestedEvent.isCancelled()) {
        return;
    }

    Object anotherNestedEvent = createOtherNestedEvent();
    eventBus.post(anotherNestedEvent);
}

我所期望的:

1. parentEvent is posted
2. parentEventHandler is called
3. nestedEvent is posted
4. handlers of nestedEvent are called
5. finished handling nestedEvent
6. if statement checks for cancel state of nestedEvent
7.     anotherNestedEvent is posted if nestedEvent not cancelled
8.     handlers of anotherNestedEvent are called
9.     finished handling anotherNestedEvent
10 finished handling parentEvent

发生了什么事

1. parentEvent is posted
2. parentEventHandler is called
3. nestedEvent is posted
4. if statement checks for cancel state of nestedEvent (defaults to false)
5.     anotherNestedEvent is posted
6. finished handing parentEvent
7. handlers of nestedEvent are called
8. nestedEvent is cancelled (too late now)
9. finished handling nestedEvent
10 handlers of anotherNestedEvent are called
11 finished handling anotherNestedEvent

在第8点,无论处理程序是否取消该事件,第二个事件都已经在队列中,因为取消检查默认为false.番石榴的EventBus坚持在开始下一个事件之前完成当前处理程序的运行,我确定它有用途,但不是我想要的.

At point 8. regardless of whether the handler cancels the event the second event has already been queued since the cancel check defaults to false. Guava's EventBus insists on finishing its current handler run before starting the next event's, which I'm sure has its uses, but its not what I'm looking for.

尝试入侵:

我注意到Guava有一个InstantDispatcher的实现( https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/Dispatcher.java#L179 )可用在事件与事件保存行为相反的情况下发布事件,直到默认PerThreadQueuedDispatcher("> https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/Dispatcher.java#L73 ).

I noticed that Guava has an implementation for an ImmediateDispatcher (https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/Dispatcher.java#L179) available that publishes events as they come in contrary to the behaviour of saving events until the current one has been handled by all subscribers of the default PerThreadQueuedDispatcher (https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/Dispatcher.java#L73).

但是,这些其他调度程序是私有程序包,EventBus上没有公共API可以更改调度程序以使用.分叉番石榴并在 https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/EventBus.java#L122 和L136到Dispatcher.immediate(),重新在另一个版本号下本地安装Guava,并且将那个自定义构建项大量添加到我的项目中,观察到的应用程序中的事件行为根本没有改变.现在我完全迷路了.

However, these other dispatchers are package private and there's no public API on the EventBus to change the dispatcher to use. Forking Guava and changing the default dispatcher at https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/EventBus.java#L122 and L136 to Dispatcher.immediate(), re-installing Guava locally under another version number, and fat jarring that custom build into my project the observed behaviour of events in the application hasn't changed at all. And now I'm completely lost.

是否可以通过Guava的EventBus来实现严格的LIFO事件分配,或者我应该关注的是另一种范式,而不是可以取消事件并经常嵌套在其他事件处理程序中的有意义的事件?我不在乎有多少和哪些订阅者收听事件,但是我确实想知道他们对事件有何评论(即,他们是否决定取消事件).该应用程序完全是单线程的.

Is there a way to achieve strict LIFO event dispatching with Guava's EventBus or is there a different paradigm I should be looking at rather than events that would make more sense when events can be cancelled and frequently end up nested in other event handlers? I don't care how many and which subscribers listen to the events, but I do want to know what they have to say about the event (i.e. whether they decided if it should be cancelled or not). The application is entirely single threaded.

推荐答案

如果您使用的是常规" EventBus,则可以通过创建辅助事件来使其正常工作.

If you're using the "regular" EventBus, you can get this to work by creating a secondary event.

添加接口InternalEventCallback和类InternalEventCallbackHandler:

interface InternalEventCallback {
    void run();
}

class InternalEventCallbackHandler {

    @Subscribe
    public void internalEventHandler(InternalEventCallback r){
        r.run();
    }
}

在创建EventBus的位置,注册InternalEventCallbackHandler:

eventBus.register(new InternalEventCallbackHandler());

然后在您的parentEventHandler中执行:

@Subscribe
public void parentEventHandler(ParentEvent parentEvent) {
    NestedEvent nestedEvent = createNestedEvent();
    eventBus.post(nestedEvent);
    eventBus.post(new InternalEventCallback() {
        @Override
        public void run() {
            if(nestedEvent.isCancelled()) {
                return;
            }

            Object anotherNestedEvent = createOtherNestedEvent();
            eventBus.post(anotherNestedEvent);
        }
    });
}

如果将AsyncEventBus与直接执行程序"一起使用,则可以得到与上例相同的行为,但没有InternalEventCallbackInternalEventCallbackHandler

If you use the AsyncEventBus together with the "direct executor", you can get the same behaviour as in the example above, but without InternalEventCallback and InternalEventCallbackHandler

EventBus eventBus = new AsyncEventBus(MoreExecutors.newDirectExecutorService());

这篇关于Guava EventBus延迟嵌套事件的处理程序执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 12:22