国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#反射內存的處理分析

2019-10-29 21:48:13
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C#反射內存的處理,較為詳細的分析了反射加載的內存釋放問題,具有一定的參考借鑒價值,需要的朋友可以參考下
 
 

本文實例分析了C#反射內存的處理。分享給大家供大家參考。具體分析如下:

這段時間由于公司的項目的要求,我利用c#的反射的機制做了一個客戶端框架。客戶端里的所有的模塊都是以一定形式進行提供,例如:FORM,UserControl. 在做的過程中很簡單與愉快。具體的過程如下:

1. 收集客戶的需求

2. 整理需求,形成必要的文檔

3. 通過討論大體的得到程序的界面風格

4. 由UI設計師設計出來具體的界面形式

5. 通過需求封裝必要的服務(我們可以使用c#的WCF服務或者JAVA的服務)

6. 制作服務管理框架

7. 封裝程序要使用到的控件

8. 編寫客戶端框架

9. 編寫模塊

10. 加載進行測試

上面說的就是簡單的一個開發的過程,當然里面包括了很多的汗水。一個好的程序都要滿足最基本的可卸載,可插入。即插件式架構。無論是客戶端,還是服務端都要采用插件式管理。

在做c#客戶端框架的時候,利用微軟的反射與工廠模式的機制的時候,里面有個很大的問題。就是通過反射的DLL加載到內存中的時候無法進行內存的釋放,只有你關閉程序的時候才進行內存的釋放,這點有很大的缺陷。我在網上也找了很多的解決的辦法,但是沒有一個能夠成功的。其中最經典的是插件的卸載的方式,這種方式我也進行的實驗,雖然能夠釋放部分內存,但是不能釋放全部的內存。我和很多程序員聊這個事情的時候,他們說把一切能釋放的都釋放掉。但是你就算做到這些也不能做到很好的釋放效果(也許的我的水平不行)。今天來吐槽一下VS的內存的釋放。VS的內存都是通過托管的機制進行資源的使用與釋放,對于非托管資源可以通過析構函數與其他的方式進行釋放。對于反射的情況微軟沒有給一個很好的辦法。如果程序員兄弟們有好的辦法提供給我們學習那將是個大的善果。

我在上面說過通過卸載插件的方式是可以釋放部分的內存,效果也還行,但是對于一些WCF服務寫的控件,在通過遠程的模式確實存在一些問題。具體的部分實現代碼如下:

復制代碼代碼如下:
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 = Assembly.LoadFrom(fullPath);
}
}


~AssemblyLoader()
{
dispose(false);
}


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


private void dispose(bool disposing)
{
if (disposing)
{
a = null;
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect(0);
}
}
#endregion
#region public functionality
public object GetObject(string typename, object[] ctorParms)
{
BindingFlags flags = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;


object o = null
;
if (a != null)
{
try
{
o = a.CreateInstance(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();
setup.ShadowCopyFiles = "true";
AppDomain domain = AppDomain.CreateDomain(dllName, null, setup);
int key=0;
foreach (DictionaryEntry de in domains)
{
if(de.Key.ToString()==dllName)
{
key++;
break;
}
}
if (key == 0)
{
domains.Add(dllName, domain);
}
object[] parms = { dllName };
BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
try
{
//al = (BCFrameWork.Client.ClientInfrm.AssemblyLoader)domain.CreateInstanceFromAndUnwrap(
// "Loader.dll", "Loader.AssemblyLoader", true, bindings, null, parms, null, null, null);
al = (AssemblyLoader)domain.CreateInstanceFromAndUnwrap(
"BestelLoadDll.dll", "BestelLoadDll.AssemblyLoader", true, bindings, null, parms, null, null, null);
}
catch
{
}
if (al != null)
{
if (!loaders.ContainsKey(dllName))
{
loaders.Add(dllName, al);
}
}
}


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

}
return o;
}


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


~ObjectLoader()
{
dispose(false);
}


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


private void dispose(bool disposing)
{
if (disposing)
{
loaders.Clear();
List removeobj = new List();
foreach (object o in domains.Keys)
{
string dllName = o.ToString();
removeobj.Add(dllName);
}
foreach (string item in removeobj)
{
Unload(item);
}
domains.Clear();
System.GC.Collect();
}
}
}

 

調用方式很簡單,如果你了解反射就知道怎么調用,這個寫法能夠滿足普通的用戶控件的反射遠程加載,但是對于一些特殊的用戶控件還是沒有辦法。

希望本文所述對大家的C#程序設計有所幫助。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南陵县| 浦北县| 苍山县| 会泽县| 湾仔区| 婺源县| 焉耆| 西安市| 象州县| 利川市| 宁陕县| 新巴尔虎左旗| 寿阳县| 台前县| 饶平县| 周宁县| 罗江县| 大新县| 宜君县| 怀集县| 东山县| 萝北县| 南涧| 濉溪县| 罗田县| 东乌珠穆沁旗| 饶平县| 蓬溪县| 静宁县| 建湖县| 康定县| 仲巴县| 玛曲县| 长寿区| 高密市| 香港 | 清徐县| 额敏县| 自治县| 清远市| 甘谷县|