Rx.net和演员模型

时间:2017-12-19 03:23:22

标签: c# async-await system.reactive

我遇到需要从方法返回IObservable<T>的情况。只要它发生了变化,就会返回对象T的新值。

对象已更改的触发器将来自actor系统,在我的示例中,我们使用的是Proto.Actor

我已经为#34; work&#34;做了一个例子,但是我觉得它没有正确实现IObservable并且不允许正确取消订阅等。

我的解决方案:

    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");
            });
        });
    }

我觉得,尽管它&#34;工作&#34;因为所有更新都被推送到订阅者,所以它永远无法准确处理,并且我不觉得while (true)应该被放入代码中,即使它是在一个单独的线程上。 / p>

我如何才能最好地处理从演员系统返回的消息列表,并将其转换为用户可以处理的IObservable(取消订阅)?

1 个答案:

答案 0 :(得分:2)

您尚未提供代码的完整工作示例,这使您难以为您提供可以复制和粘贴的工作解决方案。但是,我已经制作了一个我认为你可以使用的简化版本。

你是对的,你的解决方案不是一个好的实现。

这是您的代码的基本版本,一旦您将对象放入其中就应该正常工作:

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();
}

请告诉我这是否适合您。