[英]Reactive Extension, wrap third party API event - zero copy?
我有没有来源的第三方API。 我实例化一个回调到这样的事件:
using namespace API; // This is where APIClient lives
namespace TestApiClientUI
{
public partial class Form1 : Form
{
APIClient apiClient = new APICLient();
apiClient.QuoteUpdated += api_ClientUpdated;
private void api_ClientUpdated(object sender, string s, double b, double a)
{
}
}
}
如何将其包装到Rx Observable.FromEvent中?
另外,有没有一种方法可以使换行副本的开销尽可能少(零副本)?
让我们定义一个存储事件args的结构。
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
,实际上是向我们定义的可观察对象的订户广播一个值。 想想调用emit(value);
就像foreach (var subscriber in subscribers) { subscriber.OnNext(value); }
foreach (var subscriber in subscribers) { subscriber.OnNext(value); }
。
我们需要第一个映射的原因是因为实际的基础事件仅知道如何订阅和取消订阅ApiQuoteHandler
实例。 第二个和第三个lambda类型为Action<ApiQuoteHandler
。 分别在订阅和取消订阅上调用它们。
当IObserver<QuoteUpdate> observer
订阅我们定义的IObservable<QuoteUpdate>
,将发生以下情况:
observer.OnNext
Action<QuoteUpdate>
(类型为Action<QuoteUpdate>
)作为变量emit
传递到我们的第一个lambda中。 这将创建一个包装observer
的ApiQuoteHandler
。 ApiQuoteHandler
作为变量handler
传递到第二个lambda中。 handler
在您的apiClient
上订阅QuoteUpdated
事件。 IObservable<QuoteUpdate>
上的Subscribe
方法返回的IDisposable
包含对由我们的三个lambda中的第一个创建的ApiQuoteHandler
的引用。 IDisposable
,将使用与之前相同的ApiQuoteHandler
调用第三个lambda,取消订阅基础事件。 因为需要一个单一IObservable<T>
对于一些T
但你有事件参数(s, b, a)
必须定义一些结构或类来存储三个值。 我不必担心复制string
引用和两个double
值的成本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.