Cannot return IObservable<T> from a method marked async

async-await, c#, system.reactive

Solution

You could turn your task into an observable and combine them using `Merge`:

public IObservable<CrimeFightingResult> AllHerosFightCrime()
{
    var heros = new List<SuperHeroBase>(this);
    return heros.Select(h => h.FightCrimeAsync().ToObservable())
        .Merge();
}

If you want to maintain the order your events are received you can use `Concat` instead of `Merge`.

Problem

This contrived example is roughly how my code is structured: ``` public abstract class SuperHeroBase { protected SuperHeroBase() { } public async Task<CrimeFightingResult> FightCrimeAsync() { var result = new CrimeFightingResult(); result.State = CrimeFightingStates.Fighting; try { await FightCrimeOverride(results); } catch { SetError(results); } if (result.State == CrimeFightingStates.Fighting) result.State = CrimeFightingStates.GoodGuyWon; return result; } protected SetError(CrimeFightingResult results) { result.State = CrimeFightingStates.BadGuyWon; } protected abstract Task FightCrimeOverride(CrimeFightingResult results); } public enum CrimeFightingStates { NotStarted, Fighting, GoodGuyWon, // success state BadGuyWon // error state } public class CrimeFightingResult { internal class CrimeFightingResult() { } public CrimeFightingStates State { get; internal set; } } ``` Now I'm trying to build a collection that would hold multiple SuperHero objects and offer a `AllHerosFightCrime` method. The hero's should not all fight at once (the next one starts when the first is finished). ``` public class SuperHeroCollection : ObservableCollection<SuperHeroBase> { public SuperHeroCollection() { } // I mark the method async... public async IObservable<CrimeFightingResult> AllHerosFightCrime() { var heros = new List<SuperHeroBase>(this); var results = new ReplaySubject<CrimeFightingResult>(); foreach (var hero in heros) { // ... so I can await on FightCrimeAsync and push // the result to the subject when done var result = await hero.FightCrimeAsync(); results.OnNext(result); } results.OnCompleted(); // I can't return the IObservable here because the method is marked Async. // It expects a return type of CrimeFightingResult return results; } } ``` How can I return the `IObservable<CrimeFightingResults>` and still have the call to `FightCrimeAsync` awaited?

Original source