Welcome Guest Search | Active Topics | Sign In | Register

WPF Web Browser leaks user objects Options
ruk
Posted: Saturday, April 28, 2018 5:29:52 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
We use the EO WebBrowser in our WPF application. As our users navigate around our application, the EO browser is created and disposed when no longer needed. This creation and dispose could happen thousands of times in an applicarion process lifetime as our applications run by operators and they are required to run the application without restarting for months.

We have created a simple WPF application to reproduce this issue. We will upload the source code for this. Click on the Create button on the top middle area to create an instance of EO Web Browser. Click Dispose button to dispose the EO Web Browser instance. You can also check the Auto check box to automatically create and dispose repeatedly. Watch the User Objects count in the Task Manager. The count keeps growing as new instances are created and disposed.

Note that there is limit of 10,000 user objects per application and the application will crash when it reaches this limit.

We notice the same issue can be reproduced in the sample TabbedBrowser application. Just create new tabs to show web page and close tabs. As more tabs created and closed the user objects count keeps growing.

Our release is on hold due to this issue. This is kind of extremely urgent for us. Appreciate your help.

EO version used: 2018.0.28
eo_support
Posted: Monday, April 30, 2018 5:05:57 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Hi,

Thanks for the test application. We use the auto option and we do see a slow increase in handle count in the browser engine process. However we do not see any increase in the host process (your application process).

It may not be practical for us to chase a handle leak inside the browser engine process as the browser engine's code base is enormous (more than 16 million lines of code). So I believe the focus should be recycling this process instead. Because we do not see any leak in your host application, so it is possible for you to recycle the engine process without having to restart your application.

You can either recycle this process proactively or passively, or both. To recycle the browser engine process proactively, you can explicitly stop the browser engine periodically after you dispose your last WebView. The engine process is directly corresponds to the Engine object. You can see more option about managing Engine object here:

https://www.essentialobjects.com/doc/webbrowser/advanced/engine.aspx

To recycle this process passively, you will just let the handle leak continue until the engine process crashes, you can then respond this event by recreating one. Specifically, you would need to handle the WebView's Closed event:

https://www.essentialobjects.com/doc/eo.webbrowser.webview.closed.aspx

If you see close reason as EngineCrash in this event, that means the engine process has crashed. At which point you can proceed to create a new WebView, which will create a new engine process (or you can use the Engine interface above to explicitly create one).

Hope this helps. Please feel free to let us know if you still have any questions.

Thanks!
ruk
Posted: Monday, April 30, 2018 5:12:55 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
Thank you for looking into this. The user object leak in the main process. And this is our concern. We are seeing the user object leak every time consistently on the main process (the test application). There must be something different in your setup. We can reproduce in all our machines.

When we run Deleaker utility we do see indication that there is leak inside Eo WebControl.

By the we use Window 10 64 bit OS.
eo_support
Posted: Monday, April 30, 2018 5:38:29 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
You may want to run your test application on a clean Windows and then use monitor the task manager's handle count (go to "Details" tab, then right click column headers, click "Select Columns" to add handle column if it is not already there). We do not see handle increase there.
ruk
Posted: Monday, April 30, 2018 6:33:34 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
As I stated in the title and in the initial post above, the leak we are reporting is the "User Objects" NOT "Handles". It is the "User Objects" that are leaking. In the Task manager, details tab select the "User Objects" column and see the leak when running the sample application.
ruk
Posted: Monday, April 30, 2018 7:08:23 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
I've e-mailed a video that shows steps to reproduce.

Also in that email I've attached a screenshot of TaskManager showing the user object count reached 9,999 and application crashed.

Note that there are no issues in the sub-process, issue is only on the main process.
ruk
Posted: Monday, April 30, 2018 9:24:43 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
Here are some leads based on analysis from our team members:

1.Possible window leak in EO
Looks like there is window leak every time we create and dispose EO WebControl instance. Following is the analysis from running Spyxx tool.

We can continuously reproduce two user objects leak once we create and dispose the web control. We used Spyxx to observe the window and found there are window handles leak which came from EO. The below windows are created after we open and close the browser:

The highlighted windows were created by multiple times of open/close window which contains webbrowser and are not released. It’s about one window created per action (open/close WebBrowser)

Window 000B0A38 "SystemResourceNotifyWindow" HwndWrapper[view.exe;;623c14db-f338-4dae-957f-065ba17e74cf]
Window 00150CC2 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00270DBC "" eo.nativewnd.v18.0.28.0.0.26482361
Window 002F09DC "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00090B6A "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00B20822 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00150A08 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00040B86 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 001A0410 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 002A0D2C "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00390B1E "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00050B78 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00050C3E "" eo.nativewnd.v18.0.28.0.0.26482361
Window 000D082E "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00040C66 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 00040C62 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 005804AC "" eo.nativewnd.v18.0.28.0.0.26482361
Window 02C40BB0 "" eo.nativewnd.v18.0.28.0.0.26482361
Window 000D0A88 "" eo.nativewnd.v18.0.28.0.0.26482361


2. Another common problem in .Net code that may lead this kind of leak is not properly unregistering .Net event subscriptions. Please ensure all the events registered are unsubscribed properly. For every += in the code must have corresponding -= to unsubscribe.
For example: engine.Stopped += Engine_Stopped; should have corresponding unregister call engine.Stopped -= Engine_Stopped;
eo_support
Posted: Tuesday, May 1, 2018 8:28:39 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Thanks for the additional information. We have found the root cause of this issue. We will fix it and provide an update build as soon as possible.
ruk
Posted: Tuesday, May 1, 2018 10:16:57 AM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
Great, thank you. When can we have a build with this fix?
ruk
Posted: Tuesday, May 1, 2018 10:37:46 AM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
Can we have a hot fix on top of build 2018.0.28? I hope this may be quicker. We need the fix asap so that we can start testing on our end.
eo_support
Posted: Tuesday, May 1, 2018 2:36:30 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
We won't be able to give you hot fix directly on top a specific version but we will try to provide you a test build as soon as possible, should be in this week.
eo_support
Posted: Friday, May 4, 2018 11:31:26 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Hi,

We have posted a new build that should resolve this issue. Please see your private message for the download location.

The new build added a Dispose method to the WPF WebControl and you must call this method explicitly in your code. The TabbedBrowser sample application has been updated to reflect this change (see WebView_Closed method in MainWindow.xaml.cs/.vb).

The Dispose method is needed because WPF does not destroy the internal window handle used by a HwndHost (which is used by our WebControl control) when the corresponding WPF element is destroyed. Instead it would move it to a "parking area" where it will be destroyed when the dispatcher exits. MS implemented it this way probably to ensure that the window handle is always destroyed in the correct thread, but it does cause problem in your scenario. As a result, the underlying window handle must be destroyed explicitly when it is no longer needed. This is not possible in previous builds because neither the window handle is exposed to you nor the control provides you any method to destroy the window. This is what the newly added Dispose method is for.

Please feel free to let us know if you still have any questions.

Thanks!
ruk
Posted: Friday, May 4, 2018 1:05:11 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
Thank you for the build. We tested with this build. The user objects don't leak anymore.

However we see the handle count in the main process is steadily going up when we repeatedly create and dispose web browser control. You could see the handle growth using the test application with this build.

Also, we have a question regarding dispose. We have a derived class from EO.Wpf.WebControl and in our derived class we have dispose. Prior to consuming this build we were calling the WebView.Close with force close and WebView.Dispose.

Our derived class code prior to consuming this private build:

public void Dispose()
{
var webView = this.WebView;

if (webView != null)
{
this.UnInitialize();
webView.Close(true);
webView.Dispose();
}
}

After consuming the private build, we are calling the Dispose on the EO.Wpf.WebControl, like this:
public new void Dispose()
{
var webView = this.WebView;

if (webView != null)
{
this.UnInitialize();
//webView.Close(true);
//webView.Dispose();
}

base.Dispose();
}

However we had to comment out the webView.Close(true) and webView.Dispose() to make it work with this build. Is the Webview associated with the WebControl closed properly in your WebControl's Dispose? If so, is it force closing? We had to force close it as without this we had issues.
ruk
Posted: Friday, May 4, 2018 1:34:32 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
To see the handle growth, use the test application we uploaded earlier. After launching our test application change the URL to something like "www.msn.com" that renders more thing in the browser. Enable the "auto" check box to create and dispose webbrowser and notice the handle count growing.
ruk
Posted: Friday, May 4, 2018 6:55:57 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
We have e-mailed an updated version of our sample test application where the handle leak can be seen.
eo_support
Posted: Tuesday, May 8, 2018 11:48:57 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Hi,

We have posted a new build that should resolve this issue for you. Please see your private message for the download location.

Thanks!
ruk
Posted: Tuesday, May 8, 2018 2:04:43 PM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
We tested with the new build and don't see handle leaks. Thank you so much for the prompt responses.

We have one open item that we need your input.

What is the proper way to close the WebView instance associated to the WebControl? Strange thing is when we close the WebView instance in our dispose method (like below) we see user objects leaking.

Following dispose method is in our derived class of Eo.Wpf.WebControl
public new void Dispose()
{
this.UnInitialize();

this.WebView.Close(true);
this.WebView.Dispose();

base.Dispose();

//this.WebView.Close(true); // we tried calling after invoking the WebControl.Dispose but still user object leaks
//this.WebView.Dispose();
}

There is no user object or handle leak when we don't close the WebView in our dispose, like this:
public new void Dispose()
{
this.UnInitialize();

base.Dispose();
}

We needed to do a force close of the WebView. Wondering how we could do this without causing user object leaks.
eo_support
Posted: Thursday, May 10, 2018 8:29:36 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Hi,

You should be able to do it either way. The difference is the sequence the internal window handles are destroyed, but they should always all be destroyed. However we did notice a leak with the same code you use and we have posted a new build that should resolve the issue. Please see your private message for the download location and let us know how it goes.

Thanks!
ruk
Posted: Thursday, May 10, 2018 11:30:39 AM
Rank: Advanced Member
Groups: Member

Joined: 5/15/2017
Posts: 48
We have tested with the new private build and there are no leaks.

Thank you again for addressing this issue!
eo_support
Posted: Thursday, May 10, 2018 1:00:49 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,221
Great. Thanks for confirming the fix!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.