Reactive Extensions - 正确的方法来观察J#调用C#wrapper

时间:2016-09-10 22:22:11

标签: c# system.reactive

我正在开发一个包含Web浏览器控件的C#WinForms应用程序。该应用程序包含一个脚本桥"允许Javascript代码调用Web浏览器控件的类(我需要知道在JS代码中调用某些函数以便在WinForms应用程序中执行某些操作)。大多数这些操作都是异步的,因为当我从WinForms应用程序启动请求时,它通常会在JS代码中执行ajax请求(而不是C#代码)。由于这是一个异步操作,我试图提出一种更好/更简单的方法来管理这些异步事件的订阅/超时/错误处理等。我遇到了Reactive Extensions并决定尝试一下。

我试图确定我是否正确这样做。我试图绕过Reactive Extensions。很多Observable扩展方法很难在网上找到更简单的例子。这就是我现在正在做的事情:

public void SetupObservable()
{
    IConnectableObservable<string> javascriptResponseObservable = Observable.Create<string>(
        (IObserver<string> observer) =>
        {
            observer.OnNext("Testing");
            observer.OnCompleted();

            return Disposable.Create(() => Console.WriteLine("Observer has unsubscribed"));
        })
        .Timeout(DateTimeOffset.UtcNow.AddSeconds(5))
        .Finally(() => Console.WriteLine("Observable sequence completed"))
        .Publish();

        IObserver<string> testObserver = Observer.Create<string>(
            (value) => Console.WriteLine(value),
            (e) => Console.WriteLine("Exception occurred: " + e.Message),
            () => Console.WriteLine("Completed")
        );

    IDisposable unsubscriber = javascriptResponseObservable.Subscribe(testObserver);
}

// The following will be executed later (once the ajax request is completed)...

// Fire the event and notify all observables. If it took too long to get this point then the sequence will timeout with an exception.
public void OnSomeJavascriptFunctionCall()
{
    // Somehow get the javascriptResponseObservable object...
    javascriptResponseObservable.Connect();
}

我觉得我这样做是错误的,或者有更好的方法来实现这一目标。例如,如何检索先前创建的IObservable,以便可以调用更多方法?我是否必须坚持在课堂上或其他地方?似乎很多例子都没有这样做,所以看起来我做的事情从根本上是错误的。此外,如果多个观察者再次从不同的类等订阅IObservable,您如何跟踪IObservable?它似乎需要在创建之后保存在某个地方。是否存在某种我缺少的Observable.GetExistingObservable()方法?

1 个答案:

答案 0 :(得分:0)

  

我觉得我这样做是错误的,或者有更好的方法来实现这一点。

错误始终是一种观点,但我认为,是的,有更好的方法来解决你正在做的事情。

我认为你的JavaScript桥有某种方式来引发事件?这就是它如何能够给你回电话?如果是这样,他们您将希望利用该回调并使用define update_host { ​ $value = split($name,' ') ​ host { "${value[0]}" : ip => "${value[1]}", target => "C:/Windows/System32/drivers/etc/hosts" } } Observable.Create或其他Rx工厂方法将其桥接到Rx。

那将是你的第一步,然后你需要将你的“命令”传递给你的JS层。在发出命令以减轻任何竞争条件之前,您需要记住订阅回调序列。

很难再提供帮助,因为您只显示Rx代码似乎没有任何意义,除了试图理解Rx,没有代码显示您想要在C#-to-Js桥中实现的目标。请提供“最低完整可验证示例” - https://stackoverflow.com/help/mcve