让我们定义一个结构来存储事件参数。
struct QuoteUpdate
{
public string S { get; private set; }
public double B { get; private set; }
public double A { get; private set; }
public QuoteUpdate(string s, double b, double a) : this()
{
S = s;
B = b;
A = a;
}
}
现在我们可以定义IObservable<QuoteUpdate>
如下。
var quoteUpdates = Observable.FromEvent<ApiQuoteHandler, QuoteUpdate>(
emit => (_, s, b, a) => emit(new QuoteUpdate(s, b, a)),
handler => apiClient.QuoteUpdated += handler,
handler => apiClient.QuoteUpdated -= handler);
第一个 lambda 定义了从Action<QuoteUpdate>
到的映射ApiQuoteHandler
。被称为 的动作emit
实际上是向我们定义的可观察对象的订阅者广播一个值。把 call 想象emit(value);
成foreach (var subscriber in subscribers) { subscriber.OnNext(value); }
.
我们需要第一个映射的原因是因为实际的底层事件只知道如何订阅和取消订阅ApiQuoteHandler
实例。第二个和第三个 lambda 是 type Action<ApiQuoteHandler
。它们分别在订阅和取消订阅时调用。
当IObserver<QuoteUpdate> observer
订阅IObservable<QuoteUpdate>
我们定义的时,会发生以下情况:
observer.OnNext
(类型Action<QuoteUpdate>
)作为变量传递给我们的第一个 lambda emit
。这将创建一个ApiQuoteHandler
包装observer
.
- 然后
ApiQuoteHandler
将作为变量传递给我们的第二个 lambda handler
。handler
订阅QuoteUpdated
您的apiClient
.
- 我们的方法
IDisposable
返回的 from包含对由我们的三个 lambda 中的第一个创建的的引用。Subscribe
IObservable<QuoteUpdate>
ApiQuoteHandler
- 当稍后
IDisposable
处理它时,第三个 lambda 会以与ApiQuoteHandler
之前相同的方式调用,取消订阅基础事件。
因为你需要一个单一IObservable<T>
的T
但你有事件参数(s, b, a)
,你必须定义一些结构或类来存储三个值。我不会担心复制string
参考和两个double
值的成本。