我有一个帮助类,可以将文本消息保存到本地文件系统。此方法返回Task
对象,并且根据定义是异步的。
我希望能够观察何时调用此方法,因此我可以持续监视缓冲区的大小和长度,并根据该方法做出决定。
我正在尝试使用Reactive Extension for .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;
}
以下是我订阅observable的方式:
IObservable<Unit> receiverObservable = batchHandler.Receive(message);
receiverObservable.Subscribe(
x => Console.WriteLine("On next"),
ex => //TODO,
() => // Completed);
我希望每次调用方法Receive
时都会调用订阅者。但是,AFAIK,一旦调用此方法,observable就会完成并且序列终止,因此将不会收听对Receive
的未来调用。
有人可以推荐一种方法来使用Rx.Net库来实现我正在寻找的这种可观察模式,也就是说,如何保持序列打开并将其与异步方法的结果一起提供?
答案 0 :(得分:1)
Receive
正如您已对其进行编码,返回IObservable<Unit>
,表示单个任务的完成情况。您希望订阅返回IObservable<IObservable<Unit>>
表示任务完成流的内容。
有很多方法可以做到这一点,其中最好的方法可能取决于您的课程设置方式以及您如何调用课程。
这是最懒的一个:
您声明了一个代表您的通话流的类级变量subject
:
Subject<IObservable<Unit>> subject = new Subject<IObservable<Unit>>();
subject.Merge().Subscribe(
x => Console.WriteLine("On next"),
ex => { }, //TODO
() => { } // Completed
);
然后,当您有新的通话时,只需将其添加到主题中即可。
IObservable<Unit> receiverObservable = batchHandler.Receive(message);
subject.OnNext(receiverObservable);
这真的很懒的原因是Rx的核心是功能性的,它往往会忽视可变状态变量。 Subjects
基本上是可变状态。
更好的方法是弄清楚你何时/为什么要调用Receive
,并将其作为一个可观察的结构。一旦完成,你可以解决这个问题:
IObservable<Unit> sourceReasonsToCallReceive; // Most likely sourced from event
sourceReasonsToCallReceive.SelectMany(_ => batchHandler.Receive(message))
.SubScribe(
x => Console.WriteLine("On next"),
ex => { }, //TODO
() => { } // Completed
);
希望有所帮助。