gpt4 book ai didi

java - Guava EventBus 延迟嵌套事件的处理程序执行

转载 作者:行者123 更新时间:2023-11-30 02:00:12 24 4
gpt4 key购买 nike

我的问题与 Guava EventBus dispatching 非常相似,但虽然根本问题相似,但我尝试的修复却让我一无所知。

我有 2 个连续触发的事件。第二个事件取决于所有处理程序完成后第一个事件的最终状态。仅当第一个事件未取消时才应触发。问题是这两个事件都是从另一个事件的处理程序中触发的。

因此,虽然我不在乎谁收听第一个嵌套事件,但我确实关心他们对此有何评论。我是否已经离开了事件和 Guava 的 EventBus 旨在解决的问题空间?

考虑:

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。 Guava 的 EventBus 坚持在开始下一个事件之前完成当前处理程序的运行,我确信这有它的用处,但它不是我想要的。

尝试破解:

我注意到 Guava 有一个 ImmediateDispatcher ( 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 ) 的所有订阅者处理。

但是,这些其他调度程序是包私有(private)的,EventBus 上没有公共(public) API 来更改要使用的调度程序。 fork Guava 并将 https://github.com/google/guava/blob/master/guava/src/com/google/common/eventbus/EventBus.java#L122 和 L136 处的默认调度程序更改为 Dispatcher.immediate(),在另一个版本号下在本地重新安装 Guava,并将自定义构建到我的项目中观察到的事件行为该应用程序根本没有改变。现在我完全迷失了。

是否有一种方法可以使用 Guava 的 EventBus 实现严格的 LIFO 事件调度,或者是否有我应该考虑的不同范例,而不是当事件可以被取消并经常嵌套在其他事件处理程序中时更有意义的事件?我不在乎有多少订阅者以及哪些订阅者收听这些事件,但我确实想知道他们对事件有什么看法(即他们是否决定是否应该取消事件)。该应用程序完全是单线程的。

最佳答案

如果您使用“常规”EventBus,则可以通过创建辅助事件来使其发挥作用。

添加一个接口(interface)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

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

关于java - Guava EventBus 延迟嵌套事件的处理程序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53133014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com