繁体   English   中英

反应性扩展,包装第三方API事件-零副本?

[英]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> ,将发生以下情况:

  1. observer.OnNext Action<QuoteUpdate> (类型为Action<QuoteUpdate> )作为变量emit传递到我们的第一个lambda中。 这将创建一个包装observerApiQuoteHandler
  2. 然后,将ApiQuoteHandler作为变量handler传递到第二个lambda中。 handler在您的apiClient上订阅QuoteUpdated事件。
  3. IObservable<QuoteUpdate>上的Subscribe方法返回的IDisposable包含对由我们的三个lambda中的第一个创建的ApiQuoteHandler的引用。
  4. 当稍后处理此IDisposable ,将使用与之前相同的ApiQuoteHandler调用第三个lambda,取消订阅基础事件。

因为需要一个单一IObservable<T>对于一些T但你有事件参数(s, b, a)必须定义一些结构或类来存储三个值。 我不必担心复制string引用和两个double值的成本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM