给定:一种扩展方法,采用Selenium IWebdriver实例并返回IObservable

     public static IObservable<ObservableCollection<WebElementWrapper>>
      GetAllElementsAsObservable(this IWebDriver wd)
      {
        return Observable.Create<ObservableCollection<WebElementWrapper>>(
             (IObserver<ObservableCollection<WebElementWrapper>> observer) =>
             {
                     var eles = wd.FindElements(By.CssSelector("*"));
                     var list = eles.ToWebElementObservableCollection();
                     observer.OnNext(list);
                     observer.OnCompleted();

                 return Disposable.Create(() => { });
             });
      }


以及调用上述方法的代码(在GUI线程上运行)...

                //GUI Will Freeze on this call until OnCompleted is called
                cd.GetAllElementsAsObservable().Subscribe((WEWList) =>
                {
                    WebElementCollection = WEWList;
                    SetNavigationItems();
                });


谁能帮助我确定GUI线程阻塞的根本原因,直到调用OnCompleted。如果我在第一种方法中使用Task.Run,​​则可以停止阻塞,但随后必须将集合编组回GUI线程。

因为GUI线程启动了Observable用来提取元素的Webdriver,所以此操作是否阻塞?

还是这是由于在启动时在GUI线程上创建了静态方法?

最佳答案

如果您这样做-Disposable.Create(() => { })-您做错了什么。使用Observable.Create的使用方式是一项阻止操作。 .Create中的代码是订阅的一部分,但是您正在订阅过程中运行观察器以完成操作,这就是阻止它的原因。

尝试做这样的事情:

public static IObservable<ObservableCollection<WebElementWrapper>>
    GetAllElementsAsObservable(this IWebDriver wd)
{
    return Observable.Create<ObservableCollection<WebElementWrapper>>(observer =>
        Observable
            .Start(() =>
                wd
                    .FindElements(By.CssSelector("*"))
                    .ToWebElementObservableCollection())
            .Subscribe(observer));
}

10-04 18:50