Udostępnij za pośrednictwem


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 = "https://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

  • Anonymous
    October 16, 2008
    PingBack from http://blogs.msdn.com/vipulmodi/archive/2006/11/16/dynamic-programming-with-wcf.aspx

  • Anonymous
    October 17, 2008
    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

  • Anonymous
    October 17, 2008
    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

  • Anonymous
    October 20, 2008
    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

  • Anonymous
    October 20, 2008
    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

  • Anonymous
    November 03, 2008
    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.

  • Anonymous
    November 12, 2008
    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

  • Anonymous
    November 13, 2008
    Hi again, I found it out. In case someone else needs that: codecompileunit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration(..here goes attribute)) Enjoy, Werner

  • Anonymous
    December 18, 2008
    Does this only run on Framework 3.5 ? How can I run it on framework 2.0 ?

  • Anonymous
    June 13, 2011
    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

  • Anonymous
    December 26, 2011
    hi... How can i handle fault contract in dynamic proxy

  • Anonymous
    July 01, 2012
    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?

  • Anonymous
    January 24, 2013
    I'm also getting "Method not found". I don't know why.

  • Anonymous
    December 18, 2013
    The comment has been removed

  • Anonymous
    June 28, 2014
    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!!!