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.aspxAnonymous
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 PeresAnonymous
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 RahmanAnonymous
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 PeresAnonymous
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. KhanipourAnonymous
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, WernerAnonymous
November 13, 2008
Hi again, I found it out. In case someone else needs that: codecompileunit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration(..here goes attribute)) Enjoy, WernerAnonymous
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, MallikarjunAnonymous
December 26, 2011
hi... How can i handle fault contract in dynamic proxyAnonymous
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 removedAnonymous
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!!!