mbursill
mbursill

Reputation: 3151

Use Observable to await for event to execute

I'm trying to create an observable that listens for an event to be raised and allows me to await when it's executed. What I have so far looks like this:

    private async Task ConnectStatusMonitor()
    {
        // show the splash text
        SetSplashText("Connecting Server Status Monitor");

        var currentStatusChangedObservable = Observable.FromEventPattern(
            h => StatusManager.Instance.CurrentStatusChanged += h,
            h => StatusManager.Instance.CurrentStatusChanged -= h)
            .Take(1);

        using (currentStatusChangedObservable.Subscribe(ep => Console.WriteLine("On Next Triggered")))
        {
            await StatusMonitor.Instance.Start();

            // show the splash text
            SetSplashText("Waiting For Server Status");

            // execution awaits forever
            await currentStatusChangedObservable;
        }
    }

My StatusManager raises CurrentSatusChanged shortly after the call to Start(). I see "On Next Triggered" in my output, but it gets stuck on the last await.

I thought Take(1) would allow the Observable to know it was completed when the event had been raised once, and that awaiting on the observable would continue once the observable was completed.

Upvotes: 0

Views: 346

Answers (2)

James World
James World

Reputation: 29776

This is a classic asynchrony problem, you need to monitor for completion of any asynchronous activity before you start it. You could do this like this:

Before your first await put

var statusChanged = currentStatusChangedObservable.ToTask();

And then replace second await with

await statusChanged;

In your code as written, the final await is actually creating a second subscription to the event, which may have already fired.

Upvotes: 1

Ana Betts
Ana Betts

Reputation: 74654

A Clue: what if CurrentStatusChanged fires before you await it?

Upvotes: 0

Related Questions