Follow @RoyOsherove on Twitter

Loading Winform UI controls from a different AppDomain is problematic

I recently got a question regarding a problem loading dynamic UI controls at runtime. Part of the solution that person tried to do was to try and load the controls in a separate AppDomain, so that they can later unload those AppDomains and release the memory that the controls occupied. However - this did not work:


>We can create the usercontrols in a different appdomain but when we go
>to add the usercontrol to the launcher's container (Me.Controls.Add) in
>the default appdomain we get:
>
>"Remoting cannot find field parent on type System.Windows.Forms.Control"
>
>It does find events, the Tag property, and the Location property.
>
>It appears that the transparentproxy isn't exposing all of the
>usercontrol properties, etc.  We are not using an interface because we
>don't know what properties, methods, etc. the control container is
>expecting at run-time.  Also, we are loading UserControls so we thought
>they would expose any interfaces the container may be looking for
>(although apparently not through remoting).  All of the controls inherit
>MarshalByReference and we find no difference if we decorate them with
>.

Here's the code to reproduce this:

    Public Sub New()

        MyBase.New()

        'This call is required by the Windows Form Designer.

        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

        Dim _appDomain As AppDomain

        Dim _handle As System.Runtime.Remoting.ObjectHandle

        Dim _control As System.Windows.Forms.TextBox

        _appDomain = AppDomain.CreateDomain("TextBox")

        _control = _appDomain.CreateInstanceFromAndUnwrap("C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.Windows.Forms.dll", "System.Windows.Forms.TextBox")

        Me.Controls.Add(_control)

    End Sub

 

So why does this happen?

The problem stems from the fact that you are loading the control from a different AppDomain, and thus are essentially using remoting to talk to the control through the context boundery. Unfortunately, Remoting cannot access private members through context bounderies, which is exactly what 'parent' is in this case(inside the Control class).

MSFT.Opml

A meeting with Udi, and a talk about performance Do's and Don'ts