I have a situation where I need to return an IObservable<T>
from a method. It is to return a new value of object T
Whenever it has changed.
The trigger that the object has changed will come from the actor system, in my example we are using Proto.Actor .
I have gotten an example to "work", however I feel it is not correctly implementing IObservable
and will not allow for proper unsubscription etc.
My solution:
public IObservable<T> Watch<T>(long id)
{
var subscriber = _actorFactory.GetActor<ObjectChangedActor>();
var request = new ObjectWatchRequest(id);
return Observable.Create<T>(async (observer, cancellationToken) =>
{
await Task.Run(async () =>
{
while (true)
{
var response = await subscriber.RequestAsync<ObjectUpdatedResponse>(request, cancellationToken);
// once it gets past the above line, we have gotten notice that the object has been updated
var updatedObj = await Get<T>(id);
observer.OnNext(updatedObj);
}
}, cancellationToken);
// will this ever be called?
return Disposable.Create(() =>
{
Console.WriteLine("Disposal called");
});
});
}
I feel like, despite the fact it "works" in that all updates are pushed to the subscriber, it will never be able to accurately dispose, and I don't feel like while (true)
should ever be put in code, even when it is on a separate thread.
How would I best handle a list of messages coming back from the actor system and turning those into an IObservable
that the user can dispose of (unsubscribe)?
You haven't provided a full working example of your code, which has made it difficult to give you a working solution that you can just copy and paste. However, I've made a cut-down version that I think you can probably work from.
You're right that your solution is not a good implementation.
Here's a basic version of your code that should work about right once you put your objects in:
public IObservable<T> Watch<T>(long id)
{
return
Observable
.Defer(() =>
from x in Observable.FromAsync(() => RequestAsync())
from y in Observable.FromAsync(() => Get<T>(id))
select y)
.Repeat();
}
Let me know if this hits the mark for you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.