程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#反射內存的處置剖析

C#反射內存的處置剖析

編輯:C#入門知識

C#反射內存的處置剖析。本站提示廣大學習愛好者:(C#反射內存的處置剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是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#法式設計有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved