greenrobot / EventBus

Event bus for Android and Java that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.
http://greenrobot.org/eventbus/
Apache License 2.0
24.69k stars 4.66k forks source link

How about force background thread? #555

Open dzr1990 opened 6 years ago

dzr1990 commented 6 years ago

For my situation, I send message in sub thread, not main thread, and our most subscriber specify thread mode BACKGROUND. So my sender and subscriber are in the same thread. I think it would misleading others that background thread type is not really in the new single background thread, and BACKGROUND thread type has the same effect as POSTING. So I suggest to add a new thread type named BACKGROUND_FORCE, and in this thread type would use the really background thread, like this:


    private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
        switch (subscription.subscriberMethod.threadMode) {
            // .....
            case BACKGROUND:
                if (isMainThread) {
                    backgroundPoster.enqueue(subscription, event);
                } else {
                    invokeSubscriber(subscription, event);
                }
                break;
            case BACKGROUND_FORCE:
                backgroundPoster.enqueue(subscription, event);
                break;
            default:
                throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
        }
    }
daniele-athome commented 5 years ago

Isn't it ThreadMode.ASYNC?

dzr1990 commented 5 years ago

Isn't it ThreadMode.ASYNC?

ASYNC means all posts will be posted to CachedThreadPool, for example, I post A and B using ASYNC thread mode, it could guarantee that B would be started after starting A, but it could not guarantee B is started after A finish, but BACKGROUND_FORCE could do that, because it's single thread mode. That's why I suggest BACKGROUND_FORCE.

william-ferguson-au commented 5 years ago

IMHO you are thinking about events improperly.

When an event in your system occurs, the event should be propagated to all interested parties at some time after the event has occurred. That notification needs to occur async otherwise you have implicitly coupled your eventSource to the listener unbeknownst to either. To force notification of an event to be sent to all the listeners in a synchronous execution is pointless. They all need to be notified. They all have just as much right to be notified at the same time/speed as their sibling listeners. You are introducing coupling into your system that makes it more complex that it should be.

To argue otherwise is to argue for some kind of mediated RPC, not an EventBus.

tomridder commented 1 year ago

u can use a bool value to monitor if event A is finished. like this

private bool  isFinished  =false;

@Subscribe(ThreadMode.BackGround)   // Highest priority to always be executed first
public void onMessageEventA(A event) {
    // end of this method
   isFinished = true;
}

@Subscribe( threadMode = ThreadMode.MAIN)
public void onMessageEventB(B event) {
    while (true) {
        if (isFinished) {
           // excute B method
           isFinish == false;     
           break;
        }
    }

}