Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With C# 7.0's new TaskLike async support is it possible to write an IObservable<T> generator

C#7 is out and I see they have opened up the async await keywords to allow anything you want. However the surface area of the API seems very large and I'm not sure of the limitations.

Specifically I'm interested if this is possible

int RandomNumber(){..}

public async IObservable<int> Generate(){
    while(true){
        await Observable.Timer(TimeSpan.FromSeconds(1)).Select(_=>RandomNumber());

        await Observable.Timer(TimeSpan.FromSeconds(2)).Select(_=>10);
    }
}

which I think is equivalent to

public IObservable<int> Generate(){
   return Observable.Timer(TimeSpan.FromSeconds(1)).Select(_=>RandomNumber())
    .Concat(Observable.Timer(TimeSpan.FromSeconds(2)).Select(_=>10))
    .Replay();

}

There is a link on Reddit from a while ago discussing why async await could be as powerful as f# computation expressions if only they were allowed to be.

like image 803
bradgonesurfing Avatar asked Nov 08 '22 01:11

bradgonesurfing


1 Answers

I would guess no (for now):

The compiler has to somehow stitch together your code into a concrete type to construct and return. IObservable<T> isn't a type, so the compiler can't construct it.

Also, from 7.0 Release Notes:

The new language feature means that async methods may return other types in addition to Task, Task and void. The returned type must still satisfy the async pattern, meaning a GetAwaiter method must be accessible.

That isn't to say that someone couldn't build an ObservableTask<T> or something which would implement IObservable<T> and also fulfill the requirements of the Task API. It just hasn't been done (yet).

You still would have the issue of mismatch: Task<T> revolves around returning a 0-1 T objects, IObservable<T> returns 0-n T objects.

like image 106
Shlomo Avatar answered Nov 14 '22 22:11

Shlomo