我根据[Rx DEVHOL202]和http://rxwiki.wikidot.com/101samples#toc48
中的示例编写了一个实现这是我的代码。 http://csharp.pastebin.com/pm2NAPx6
它可以工作,但对OnNext的调用不是NonBlocking,这是我想要实现的模拟网络读取和异步处理每个字节块,因为它被读取到处理程序[不是这里显示完整但可能会缓存结果并进行进一步处理]。
这样做的好方法是什么?
抛出异常后,所有后续的OnNext()都不会被处理!! 如果我没有明确退出循环并指示完成。 为什么会这样?
答案 0 :(得分:2)
我强烈建议反对尝试实施您自己的IObservable
。隐式规则超出了线程安全性和方法调用顺序。
通常你会从方法中返回IObservable
个实例,但是如果你需要一个直接实现它的类,你应该包装一个Subject
:
public class SomeObservable<T> : IObservable<T>
{
private Subject<T> subject = new Subject<T>();
public IDisposable Subscribe(IObserver<T> observer)
{
return subject.Subscribe(observer);
}
}
1。您需要注意观察者如何支持这一点(因为您可能有共享数据),但您可以通过以下两种方式之一异步处理调用:
ObserveOn(Scheduler.TaskPool)
之前,请致电ThreadPool
(如果您是4.0之前,请Subscribe
)。这会导致消息通过调度程序(在本例中为任务)进行路由IScheduler
传递给Observer
构造函数 2。这是预期的功能。 IObservable
和IObserver
之间的合同是(OnNext)* (OnCompleted | OnError)?
,也就是说“对OnNext进行零次或多次调用,可选地后跟EITHER OnCompleted或OnError”。在OnCompleted|OnError
之后,调用OnNext
无效。
Rx中的所有运算符(Where
,Select
等)都会强制执行此规则,即使源不符合此规则。
答案 1 :(得分:0)
我不确定我是否正确理解了你的问题,但为什么你不能在不同的Thread
上执行你所拥有的任何逻辑,或者如果它足够小就可以将它推到ThreadPool
上?
以下是一个例子:
ThreadPool.QueueUserWorkItem(o=>
{
_paidSubj.OnNext(this); // Raise PAID event
});
我对Subject
上的数据类型感到困惑,我从未见过C#中的那个类......是你创建的吗? OnNext
是一个被引发的事件还是一个方法?如果OnNext
是一个事件,那么您可以使用BeginInvoke
异步调用它:
_paidSubj.OnNext.BeginInvoke(this, null, null);
<强>更新强>
如果实现这种异步行为,将会发生一件重要的事情:如果通过传递IObserver
通知Order
,当您尝试读取数据时,实际上可能会有一些不一致订单继续修改其Read
线程中的缓冲区时,观察者(即订单缓冲区)。所以至少有两种方法可以解决这个问题:
P.S。
你从哪里得到Subject
? Subject
应该是OrderObserver
吗?