Avoiding possible problems caused by .NET controls exposed via ActiveX

Microsoft .Net Logo (Source File, .jpg)zenon allows the use of ActiveX controls for extending the user interface. A series of Information Unlimited articles shows how such ActiveX controls can be created using a .NET Framework programming language. As the .NET Framework is managed code, the .NET ActiveX controls are  destroyed by a garbage collector at any time if the reference count reaches zero. Additionally, the garbage collector must recognize that the ActiveX control is not referenced by any other object in order to be able to destroy it. This managed way of destroying .NET ActiveX controls can lead to serious problems.

Problems that might occur with .NET ActiveX controls with a simple user interface

One problem that might occur is that there is no garbage collection between closing a screen in zenon Editor and closing zenon Editor itself. A .NET ActiveX control that hasn’t been destroyed when zenon Editor is closing causes the zenon Editor process to remain active after closing the zenon Editor window. Since there can only be one running zenon Editor instance on a computer, this leads to problems when zenon Editor is started again:

  • If it is started by a different user, the user trying to start zenon Editor will receive an error message that another user is currently using it although the other user has closed zenon Editor.
  • If it is started again by the same user, zenon Editor will show up immediately but without a workspace loaded. If the user then tries to load a workspace, zenon Editor crashes, because it is in the terminating state after hiding the main window and therefore no longer ready for user interactions.

In zenon Runtime this problem also might occur, but zenon Runtime terminates after running through its teardown routines without waiting for garbage collection of .NET ActiveX controls.
To fix this issue, garbage collection is triggered on closing screens in zenon 7.10 and higher.

Problems that do occur with .NET ActiveX controls with a complex user interface

But what happens if the garbage collector cannot recognize an object as deletable and when does this occur? If a .NET ActiveX control reaches a certain user interface complexity (child controls nested in other child controls, event handlers for those child controls and object members holding a reference to the control), the garbage collector cannot recognize the control object as deletable after the screen hosting it is closed. If that occurs, the problems described above will occur, in addition to leaking memory every time a screen with such a .NET ActiveX control is shown. As the mentioned fix only triggers garbage collection, it does not resolve problems caused by such .NET ActiveX controls.

So what can be done to resolve this problem (apart from not using .NET ActiveX controls)? First of all, it is recommended to avoid instance members holding a reference to the control wherever it is possible. If there is no way to avoid such members, they have to be cleared in the same method where the user interface is cleared (see below). As it is the complex user interface that prevents the garbage collector from destroying the object, the user interface objects must be cleared when the user interface is no longer needed. This can be done by implementing the .NET ActiveX control methods

zenOnExit

and

zenOnExitEd

and calling

Dispose

in both those methods. The following code sample is given as an example:

public bool zenOnExit()
{
Dispose();
return true;
}
public bool zenOnExitEd()
{
Dispose();
return true;
}

With this knowledge it is easy to avoid the described problems by simply including the two zenon exit methods in every .NET ActiveX control that is used.

Tags: ,

Leave a Reply