Given: An extension method taking a Selenium IWebdriver instance and returning an 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(() => { });
});
}
And the code that calls the method above (running on GUI thread)...
//GUI Will Freeze on this call until OnCompleted is called
cd.GetAllElementsAsObservable().Subscribe((WEWList) =>
{
WebElementCollection = WEWList;
SetNavigationItems();
});
Can anyone help me determine root cause of GUI thread block until OnCompleted is called. I can stop the blocking if I use Task.Run in first method, but then I have to marshall the collection back onto GUI thread.
Does this block because the GUI thread spun up the Webdriver of which the Observable is using to extract elements?
Or is this due to the static methods being created at start up time on the GUI thread?
If ever you do this - Disposable.Create(() => { }) - you are doing something wrong. Using Observable.Create the way you are using it is a blocking operation. The code inside the .Create is part of the subscription, but you're running the observer to completion during subscription which is why it is blocking.
Try doing something like this instead:
public static IObservable<ObservableCollection<WebElementWrapper>>
GetAllElementsAsObservable(this IWebDriver wd)
{
return Observable.Create<ObservableCollection<WebElementWrapper>>(observer =>
Observable
.Start(() =>
wd
.FindElements(By.CssSelector("*"))
.ToWebElementObservableCollection())
.Subscribe(observer));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With