Dynamic Proxy and Memory Footprint


A while back I published a post about dynamic programming with WCF using the dynamic proxy library that allows you to create WCF client dynamically at runtime. Thank you for using the sample and sending your comments. Frequently I get feedback about the memory usage of the applications using this library. It seems that if you create many dynamic proxies during the lifetime of your application, the memory footprint keeps growing. This is a common problem that you encounter when using any dynamically created assembly in your application. You need to aware of this issue and take appropriate measure to make sure that you are not leaking memory.


The dynamic proxy creates the proxy assembly at runtime; this assembly is stored in a temporary location on your file system and loaded in the memory of your app domain. Now if you do not need the dynamic proxy anymore, there is no way to unload this temporary assembly. There isn’t. You need to unload the entire app domain. So what should you do if you need to create and destroy many dynamic proxies in your application? Simply, isolate the code that is creating and using the dynamic proxy and run it in a different app domain. Once you are done, simply unload that app domain.


Here is a simple modification to the example program from the dynamic proxy library that runs the dynamic client in a new app domain. You will notice that the memory footprint of the application remains the same over large number of iterations.


class Program


{


    public static void Main(string[] args)


    {


        string serviceWsdlUri = "http://localhost:8080/WcfSamples/DynamicProxy?wsdl";


        if (args.Length > 0)


        {


            serviceWsdlUri = args[0];


        }


 


        for(int i = 0; i < 1000; i++)


        {


            AppDomain proxyDomain = AppDomain.CreateDomain("ProxyExecutionDomain");


            DynamicClient dynamicClient = new DynamicClient(serviceWsdlUri);


            proxyDomain.DoCallBack(


              new CrossAppDomainDelegate(dynamicClient.CrossAppDomainCallback));


            AppDomain.Unload(proxyDomain);


            GC.Collect();


        }


    }


}


 


[Serializable]


class DynamicClient


{


    string serviceWsdlUri;


 


    public DynamicClient(string serviceWsdlUri)


    {


        this.serviceWsdlUri = serviceWsdlUri;


    }


 


    public void CrossAppDomainCallback()


    {


        // create the dynamic proxy factory, that downloads the service metadata


        // and create the dynamic factory.


        Console.WriteLine("Creating DynamicProxyFactory for " + serviceWsdlUri);


        DynamicProxyFactory factory = new DynamicProxyFactory(serviceWsdlUri);


...


 


Comments (15)

  1. Ricardo Peres says:

    Hi, Vipul, thanks for your post!

    What if we wanted to change the DynamicProxyFactory so that it has a member field of type AppDomain where all new types (and their assemblies) are placed; DynamicProxyFactory is also changed in order to implement IDisposable, and in the Dispose() method, the AppDomain is unloaded.

    I tried to change your code, but I always get a "Type is not resolved for member ‘_MyClassName_here_’".

    Can you help?

    Thanks!

    Ricardo Peres

  2. Rahman says:

    First, i must thank u for this great work!!!

    I have a question: How can i call my service’s Methods asynchronously? i want to use asynchronous operations by using this Library(Dynamic Proxy) but i haven’t found any way.

    Could u help me ….

    thanks

    Rahman

  3. Ricardo Peres says:

    Hi, Rahman!

    You can do that easily by using delegates.

    For example, suppose you have a method like this:

    public void DoSomething(int i) { … }

    You can define a delegate with signature

    public delegate void DoSomethingDelegate(int i);

    And then invoke DoSomething asynchronously:

    DoSomethingDelegate del = new DoSomethingDelegate(DoSomething);

    IAsyncResult result = del.BeginInvoke(i, null /*callback*/, null /*context*/);

    If you want, you can pass a pointer to a method as the callback argument, it will be called when the asynchronous call terminates.

    Hope this helps!

    Ricardo Peres

  4. Rahman says:

    Hi, Ricardo

    Thanks for your Reply! it was useful But i should tell u that i meant How could i call asynchronous WCF service Methods BY Using DynamicProxy Library!!! because in DynamicProxy Library we call methods a little different(using DynamicProxy.CallMethod() )!

    I don’t know maybe your way solves it but i changed WCF DynamicProxy Library and i added a property that asynchronous Operations are generated Dynamically for WCF service methods!

    i will published the changed library in the CodeProject Site very Soon.

    I Hope it will be useful …

    R. Khanipour

  5. You can update the code to set appropriate options so that async operations are generated. You can then use the CallMethod to call the Begin/End methods or add a wrapper BeginCallMethod/EndCallMethod.

  6. Werner says:

    Hi Vipul,

    Thank you for a great solution!

    I’d like to decorate the generated code in the assembly with an attribute (i.e. AllowPartiallyTrustedCallersAttribute) but couldn’t figure out how to do that.

    May I ask you for some hints to go about that?

    Thank you, Werner

  7. Werner says:

    Hi again,

    I found it out. In case someone else needs that:

    codecompileunit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration(..here goes attribute))

    Enjoy,

    Werner

  8. Andrew says:

    Does this only run on Framework 3.5 ?

    How can I run it on framework 2.0 ?

  9. Mallikarjun says:

    Hi ,

    I have a problem using the complex types as parameters in the dynamic proxy. These parameter types are only known at Run time. I mean the method name, parameters are dynamic. So when i try to call any method with complex type, i get the error "Method not found". Can you please provide solution/Workaround for this.

    Thanks,

    Mallikarjun

  10. Rahul says:

    hi… How can i handle fault contract in dynamic proxy

  11. programmer says:

    Hi, How can I access custom Types that I created in my WCF Service. I can access any method on a Class/Type I created. But directly If I want to access a custom Type that I created in the WCF service?

  12. I'm also getting "Method not found". I don't know why.

  13. shsh says:

    Hi, Thanks…

    1. Today (framework 4.5), there is a better way to call dynamically the wcf?

    2. I want to get a return value from the service, and I'm writing Infrastructure component for executing services, so it will work for many times calling services – and I need to keep not get memory leak, how can I do it?

  14. Rajesh Kumar says:

    Hi Vipul,

      First i want to thanks for your great work you have done…. Thanks a lot ….

     I am facing a problems sending a custom parameter while invoke the method… Please help me to fix this…

    Type proxyType = proxy.ProxyType;

    proxyType.CallMethod("Ping",objParams);

    Here the ping method needs the parameter type "Message". i have send the xml value in string to invoke the method. It shows the error….

    Please help me to fix problem . How to send the custom parameter while invoking the method..

    MethodInfo[] methods = proxyType.GetMethods();

                   foreach (var method in methods)

                   {

                       ddlMethods.Add(method.Name);

                       if (methodName == "Ping")

                       {

                           var objresult = method.Invoke(proxy.ObjectInstance, objparams);

                      }

    Thanks in advance!!!

Skip to main content