响应式扩展——在c#包装器中观察Javascript调用的正确方法

本文关键字:调用 Javascript 观察 方法 扩展 响应 包装 | 更新日期: 2023-09-27 18:06:26

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

我正试图确定我是否这样做是正确的。我正在努力理解响应式扩展。对于许多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()方法的某种类型,我错过了?

响应式扩展——在c#包装器中观察Javascript调用的正确方法

我觉得我做这件事的方式是错误的,或者有更好的方法来完成这件事。

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

我假设你的JavaScript桥有某种方式引发事件?它就是这样给你回电话的吗?如果是这样,他们会想要利用回调并使用Observable.Create, Observable.FromEvent*或另一个Rx工厂方法将其桥接到Rx。

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

很难再提供帮助了,因为你只展示了除了试图理解Rx之外似乎没有任何目的的Rx代码,并且没有代码显示你试图在c#到js的桥中实现什么。请提供"最小完整可验证示例"- https://stackoverflow.com/help/mcve