SoFunction
Updated on 2025-03-07

Processing and analysis of C# reflective memory

This article analyzes the processing of C# reflected memory. Share it for your reference. The specific analysis is as follows:

During this period, due to the requirements of the company's project, I used the C# reflection mechanism to create a client framework. All modules in the client are provided in a certain form, such as: FORM, UserControl. The process is simple and pleasant. The specific process is as follows:

1. Collect customer needs

2. Organize requirements and form necessary documents

3. Through discussion, we can obtain the interface style of the program

4. The specific interface form is designed by the UI designer

5. Encapsulate necessary services through requirements (we can use C# WCF service or JAVA service)

6. Create a service management framework

7. The controls to be used by the encapsulation program

8. Write client framework

9. Write modules

10. Load for testing

What is mentioned above is a simple development process, which of course includes a lot of sweat. A good program must meet the most basic uninstallable and pluggable. That is, plug-in architecture. Both the client and the server must adopt plug-in management.

When working on the C# client framework, there is a big problem when using Microsoft's reflection and factory model mechanisms. It is impossible to release memory when loaded into memory through reflected DLLs. Only when you close the program, memory will be released. This has a big drawback. I have also found many solutions online, but none of them have succeeded. The most classic one is the uninstallation method of plug-ins. I also conducted experiments in this method. Although it can free up part of the memory, it cannot free up all the memory. When I talk to many programmers about this, they say that they can release everything they can. But even if you do this, you cannot achieve a good release effect (maybe my level is not good). Today I will complain about the release of VS memory. VS memory is used and released through a hosting mechanism, and unmanaged resources can be released through destructors and other methods. Microsoft has not given a good solution for reflection situations. If programmers and brothers have a good way to provide us with learning, it would be a great result.

I said above that the method of uninstalling the plug-in can free up part of the memory, and the effect is OK, but for some controls written by WCF services, there are indeed some problems in remote mode. The specific implementation codes are as follows:

Copy the codeThe code is as follows:
internal class AssemblyLoader : MarshalByRefObject, IDisposable
{
#region class-level declarations
private Assembly a = null;
#endregion


#region constructors and destructors
public AssemblyLoader(string fullPath)
{
if (a == null)
{
a = (fullPath);
}
}


~AssemblyLoader()
{
dispose(false);
}


public void Dispose()
{
dispose(true);
}


private void dispose(bool disposing)
{
if (disposing)
{
a = null;
();
();
(0);
}
}
#endregion
#region public functionality
public object GetObject(string typename, object[] ctorParms)
{
BindingFlags flags = | | ;


object o = null
;
if (a != null)
{
try
{
o = (typename, true, flags, null, ctorParms, null, null);
}
catch
{
}
}
return o;
}


public object GetObject(string typename)
{
return GetObject(typename, null);
}
#endregion

 

public class ObjectLoader : IDisposable
{
// essentially creates a parallel-hash pair setup
// one appDomain per loader
protected Hashtable domains = new Hashtable();
// one loader per assembly DLL
protected Hashtable loaders = new Hashtable();


public ObjectLoader()
{}


public object GetObject(string dllName, string typeName, object[] constructorParms)
{
AssemblyLoader al = null;
object o = null;
//Type t = null;
try
{
al = (AssemblyLoader)loaders[dllName];
}
catch (Exception) { }


if (al == null)
{
AppDomainSetup setup = new AppDomainSetup();
= "true";
AppDomain domain = (dllName, null, setup);
int key=0;
foreach (DictionaryEntry de in domains)
{
if(()==dllName)
{
key++;
break;
}
}
if (key == 0)
{
(dllName, domain);
}
object[] parms = { dllName };
BindingFlags bindings = | | ;
try
{
//al = ()(
// "", "", true, bindings, null, parms, null, null, null);
al = (AssemblyLoader)(
"", "", true, bindings, null, parms, null, null, null);
}
catch
{
}
if (al != null)
{
if (!(dllName))
{
(dllName, al);
}
}
}


if (al != null)
{
o = (typeName, constructorParms);

}
return o;
}


public void Unload(string dllName)
{
if ((dllName))
{
AppDomain domain = (AppDomain)domains[dllName];
(domain);
(dllName);
}
}


~ObjectLoader()
{
dispose(false);
}


public void Dispose()
{
dispose(true);
}


private void dispose(bool disposing)
{
if (disposing)
{
();
List removeobj = new List();
foreach (object o in )
{
string dllName = ();
(dllName);
}
foreach (string item in removeobj)
{
Unload(item);
}
();
();
}
}
}

The calling method is very simple. If you understand reflection, you will know how to call it. This writing method can satisfy the remote loading of reflections of ordinary user controls, but there is still no way to do it for some special user controls.

I hope this article will be helpful to everyone's C# programming.