C# Rx.Net:独立观察异步事件

C# Rx.Net:独立观察异步事件,c#,asynchronous,rx.net,C#,Asynchronous,Rx.net,我有一个助手类,它将文本消息保存到本地文件系统。此方法返回任务对象,并且根据定义是异步的 我希望能够观察这个方法何时被调用,这样我就可以连续监视缓冲区的大小和长度,并基于此做出决定 我正在尝试使用.NET的被动扩展来实现这一点。然而,我不能想出一个设计,让我不断地听取消息被添加到缓冲区。以下是我目前的执行情况: public IObservable<Unit> Receive(InternalMessage message) { var obs

我有一个助手类,它将文本消息保存到本地文件系统。此方法返回任务对象,并且根据定义是异步的

我希望能够观察这个方法何时被调用,这样我就可以连续监视缓冲区的大小和长度,并基于此做出决定

我正在尝试使用.NET的被动扩展来实现这一点。然而,我不能想出一个设计,让我不断地听取消息被添加到缓冲区。以下是我目前的执行情况:

public IObservable<Unit> Receive(InternalMessage message)
        {
            var observable = FileBuffer.BufferMessage(message.MessageId.ToString(), message, DateTime.UtcNow).ToObservable(); //This returns a Task, which I convert into an Observable
            return observable;
        }
以下是我对可观察事物的看法:

IObservable<Unit> receiverObservable = batchHandler.Receive(message);
            receiverObservable.Subscribe(
                x => Console.WriteLine("On next"),
                ex => //TODO,
                () => // Completed);
我希望每次调用Receive方法时都调用订阅服务器。然而,好吧,一旦调用了这个方法,可观察对象就完成了,序列也就终止了,所以将来的Receive调用就不会被监听

有人能推荐一种使用Rx.Net库来实现我正在寻找的可观察模式的方法吗?也就是说,如何保持序列的开放性并为其提供异步方法的结果?

在编码时接收,返回IObservable,表示单个任务的完成。您希望订阅返回表示任务完成流的IObservable的内容

有很多方法可以做到这一点,其中最好的方法可能取决于类的设置和调用方式

下面是最懒的一个:

声明表示调用流的类级变量subject:

Subject<IObservable<Unit>> subject = new Subject<IObservable<Unit>>();
subject.Merge().Subscribe(
    x => Console.WriteLine("On next"),
    ex => { },  //TODO
    () => { }   // Completed
);

希望这能有所帮助。

为什么不在FileBuffer中创建事件,每次缓冲消息时都会调用该事件,然后订阅此事件?我无法访问FileBuffer代码来更改它。我可以向BatchHandler类添加一个事件,但我想看看我是否可以通过Rx本机解决这个问题,因为它提供的用于管理序列和组合的工具将来可能会对我有所帮助。您可以将事件添加到BatchHandler,然后使用Observable.FromEvent创建序列。另外一个好处是事件易于理解和使用,您可以按原样使用它们或生成可观察的序列。
IObservable<Unit> receiverObservable = batchHandler.Receive(message);
subject.OnNext(receiverObservable);
IObservable<Unit> sourceReasonsToCallReceive; // Most likely sourced from event

sourceReasonsToCallReceive.SelectMany(_ => batchHandler.Receive(message))
    .SubScribe(
    x => Console.WriteLine("On next"),
    ex => { },  //TODO
    () => { }   // Completed
);