Geteventstore ClientAPI (4.0.0 - 4.0.3) changes - How do you ensure events on streams get processed in the correct order?

With regard to geteventstore (https://eventstore.org/) using c#

EventStore.ClientAPI, Version=4.0.0.7 has the method below…

EventStoreStreamCatchUpSubscription SubscribeToStreamFrom(string stream, long? lastCheckpoint, CatchUpSubscriptionSettings settings, Action<EventStoreCatchUpSubscription, ResolvedEvent> eventAppeared, Action liveProcessingStarted = null, Action<EventStoreCatchUpSubscription, SubscriptionDropReason, Exception> subscriptionDropped = null, UserCredentials userCredentials = null);

This allows you to subscribe to a stream and supply an eventAppeared Action which gets called each time an event occurs in the order events occur.
Now if you upgrade the client to…

EventStore.ClientAPI, Version=4.0.3.0

The method has changed slightly, you now supply an asyncronous function for eventAppeared that returns a task…

EventStoreStreamCatchUpSubscription SubscribeToStreamFrom(string stream, long? lastCheckpoint, CatchUpSubscriptionSettings settings, Func<EventStoreCatchUpSubscription, ResolvedEvent, Task> eventAppeared, Action liveProcessingStarted = null, Action<EventStoreCatchUpSubscription, SubscriptionDropReason, Exception> subscriptionDropped = null, UserCredentials userCredentials = null);

My question is… Does each one of these tasks get awaited within geteventstore? In other words it gets one event, passes it to the supplied eventAppeared, waits for that eventAppeared to complete, gets the next event, passes it to the supplied eventAppeared, waits for that eventAppeared to complete…etc

So say if eventAppeared just took the event and wrote them out to another stream, if events on the stream you subscribed to contained (1),(2),(3),(4) in consecutive events the events in the stream you wrote out to would contain (1),(2),(3),(4) in consecutive events.

Or does it simply get each event on the stream and use eventAppeared to create a task for it and set it running, so multiple tasks could all be running concurrently in whatever order the OS decides. In this case the stream you wrote out to could quite possibly contain something like (1),(4),(3),(2) in consecutive events?

I can see both ways have their advantages… awaiting ensures the order eventAppeared does work is preserved, whereas not awaiting the tasks may give higher performance.

It awaits in order, behaving the same as the synchronous version.

https://github.com/EventStore/EventStore/blob/daddeca886f43e40489efd7d9f45cb6ddd4aed8a/src/EventStore.ClientAPI/ClientOperations/SubscriptionOperation.cs#L274

If you wanted, you could always push the event or even a task to your own user-side container/thread to parallelize it, for example the following callback would handle up to 5 events in parallel,