Skip to content

[Enhancement] Add awaitable Publish for async subscribers #3396

@tazayan

Description

@tazayan

Summary

Propose adding a new event type, FanOutFanInEvent<TPayload> or AsyncPubSubEvent<TPayload>, to Prism.Events that supports asynchronous subscribers (Func<TPayload, Task>) and an awaitable Publish method.

Unlike PubSubEvent<TPayload>, this event would return a Task from Publish, allowing publishers await completion of all subscribed handlers or CancellationToken trigger. This would preserve the familiar publish/subscribe model from EventBase, while making event handling more natural in modern async/await-based applications.

API Changes

Example shape of the proposed API:

class FanOutFanInEvent<TPayload> : EventBase
{
    public SubscriptionToken Subscribe(Func<TPayload, Task> action)
    { 
        // ...
    }

    /// returns Task that completes when all handlers have completed processing
    /// or cancellationToken has been triggered
    /// cancellationToken is not used to cancel the handlers, it is only used to cancel
    /// waiting for the handlers to complete
    public async Task Publish(TPayload payload, CancellationToken cancellationToken = default)
    {
        List<Func<TPayload, Task>> executionStrategies = ...;

        await Task.WhenAll(executionStrategies.Select(x => x.Invoke(payload)))
            .WaitAsync(cancellationToken);
    }
}
  • Publish returns a Task that completes when all handlers complete or if the provided CancellationToken is cancelled, it cancels only the waiting operation, not the subscriber handlers themselves
  • Exceptions from handlers could be surfaced using Task.WhenAll behavior or can be manually Aggregated
  • Could support existing Prism threading semantics such as PublisherThread, BackgroundThread, and UIThread

Threading Model

One important aspect of this proposal is that it can support different threading models, similar to existing Prism event subscriptions:

  • PublisherThread: today, PubSubEvent.Publish completes only after all handlers have finished executing and propagates subscriber exceptions back to the caller. The proposed event would preserve similar semantics, while allowing handlers to be asynchronous and the publisher to await overall completion.
  • BackgroundThread: handlers can be scheduled onto background execution.
  • UIThread: handlers can be dispatched through the existing synchronization context model.

This would make the new event type feel consistent with the current Prism eventing model, rather than introducing a completely separate abstraction.

Intended Use Case

In modern .NET applications, almost all event subscribers perform asynchronous work such as:

  • HTTP requests
  • file I/O

Today, native support for Task-based subscribers would make Prism events feel much more natural in async/await workflows.

The proposed Publish behavior also has strong conceptual similarity to regular PubSubEvent.Publish: a publisher raises an event and all subscribers are invoked. The difference is that this new event type gives the publisher an awaitable completion point, making it possible to coordinate continuation logic after all handlers have finished.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions