例如下边一段代码中
1. public unsafe void getLocation(object nothing)
        {
           // PublicClass.Tools.gpsOpen();
            GPSManage.GPSPosition myPostion=PublicClass.Tools.objgps.GetPosition();
            makerClickdelegate mydelegate=new makerClickdelegate(makerClick);
            
           if(myPostion==null)
            {
                return;
            }
            if (myPostion.LatitudeValid && myPostion.LongitudeValid && myPostion.TimeValid)
            {
                
                PublicClass.Tools.nowPosition = myPostion;
                currPosition = myPostion;
                MMarkerOptions currmaker = this.mapCtrl1.GetMarkerOptions("当前位置");                if (currmaker.ToString() != null)
                {
                    this.mapCtrl1.RemoveMarker("当前位置");
                }
                MMarkerOptions erOptions = new MMarkerOptions();
                sbyte[] cID = new sbyte[128];
                MMap.UnicodeToAnsi(cID, "当前位置");
                erOptions.cID = cID;
               // erOptions.LonLat.fLon = FromGpsToLonlat(myPostion).fLon;
                //erOptions.LonLat.fLat = FromGpsToLonlat(myPostion).fLat;
                erOptions.LonLat.fLon = FromGpsToLonlat(myPostion).fLon;
                erOptions.LonLat.fLat = FromGpsToLonlat(myPostion).fLat;
                erOptions.lWidth = 34;
                erOptions.lHigh = 32;
                erOptions.bIsImagePos = true;
                erOptions.ImagePos.fX = 0;
                erOptions.ImagePos.fY = 0;
                string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().
                GetName().CodeBase);
                string imagePath = path + "\\Image\\er.png";
                sbyte[] cImagePath = new sbyte[128];
                MMap.UnicodeToAnsi(cImagePath, imagePath);
                erOptions.cImagePath = cImagePath;
                sbyte[] cName = new sbyte[128];
                MMap.UnicodeToAnsi(cName, "宋体");
                erOptions.LabelOption.FontStyle.cName = cName;
                erOptions.LabelOption.FontStyle.lfWidth = 12;
                erOptions.LabelOption.FontStyle.lfHeight = 12;
                erOptions.LabelOption.FontStyle.ulColor = MMap.rgb(255, 0, 0);
                erOptions.LabelOption.FontStyle.bBold = true;
                IntPtr functionPointer = Marshal.GetFunctionPointerForDelegate(mydelegate);
                erOptions.pOnClickFunc = functionPointer;
                //erOptions.pOnClickFunc = IntPtr.Zero;
                sbyte[] text = new sbyte[256];
                MMap.UnicodeToAnsi(text, "当前位置");
                erOptions.LabelOption.cText = text;
                erOptions.bIsLabelPos = true;
                erOptions.LabelPos.fX = 10;
                erOptions.LabelPos.fY = 10;
                mapCtrl1.AddMarker(ref erOptions);
                this.mapCtrl1.SetMapCenter(FromGpsToLonlat(myPostion));
                int Lastlevel = int.Parse(mapInfi.IniReadValue("MapLevel", "Level"));
                this.mapCtrl1.SetZoomLevel(Lastlevel);
                
            }
            else
            {
                return;
            }        }
垃圾回在什么时刻回收mydelegate的引用?
请明白的人给解释解释。谢谢!

解决方案 »

  1.   

    当clr认为应该回收的就回收了~~~~~.net的垃圾回收机制和vc不同,vc需要手动回收,clr自动回收
      

  2.   

    恩,感谢回复。能说的再具体些吗?比如clr会在什么情况下认为该回收了。我们怎么可以在程序中手动的保留垃圾回收的资源呢?
      

  3.   

    这个真不是一句两句能说清的呵呵,我也不想从网上抄一大堆文字来蹭你的分~~~这个建议你百度“clr 垃圾回收机制”、“clr 运行机制”等搜索一下,了解一下clr的原理,对以后的提高会有帮助的。
    如果你现在还不了解托管和非托管,那么讲clr也会听的一头雾水。
    建议夯实基础,先把代码学好,在学习的过程中遇到问题再找解决方案。也许你现在学习到了委托这里卡在这儿了,想弄懂clr原理,这样很容易累的,建议先把这点东西放放,继续学习,弄明白了委托和事件,等你回头一看,可能就会豁然开朗了
      

  4.   

    比如说一个公司(场景),你是老板,手下有两个员工,小张和小王。
    你命令小王,如果小张玩游戏,则小王扣去小张500元钱。这就是现实中的委托。实际上,在写程序中,程序员就是老板,小张和小王就是两个对象。小张玩游戏是一个方法,小张还有一个游戏事件,他玩游戏激发这个事件。而小王就是事件处理对象,他负责把小张的钱扣除500。所以,委托有如下几个要素:
    1 激发事件的对象--就是小张
    2 处理对象事件的对象--就是小王
    3 定义委托,就是你让小王监视小张。如果这三个要素都满足的话,则你就写出了一个完整事件的处理。下面有个例子:在vs.net2003 C#控制台应用程序编辑运行成功:
    using System;namespace CSharpConsole
    {
    public class 场景
    {
    [STAThread]
    public static void Main(string[] args)
    {
    Console.WriteLine("场景开始了....");
    // 生成小王
    小王 w = new 小王();
    // 生成小账
    小张 z = new 小张();// 指定监视
    z.PlayGame += new PlayGameHandler(w.扣钱);// 开始玩游戏
    z.玩游戏();Console.WriteLine("场景结束...");
    Console.ReadLine();
    }
    }// 负责扣钱的人
    public class 小王
    {
    public 小王()
    {
    Console.WriteLine("生成小王...");
    }public void 扣钱(object sender,EventArgs e)
    {
    Console.WriteLine("小王:好小子,上班时间胆敢玩游戏...");
    Console.WriteLine("小王:看看你小子有多少钱...");
    小张 f = (小张)sender;
    Console.WriteLine("小张的钱: " + f.钱.ToString());
    Console.WriteLine("开始扣钱......");
    System.Threading.Thread.Sleep(500);
    f.钱 = f.钱 - 500;
    Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString());
    }
    }// 如果玩游戏,则引发事件
    public class 小张
    {
    // 先定义一个事件,这个事件表示“小张”在玩游戏。
    public event PlayGameHandler PlayGame;
    // 保存小张钱的变量
    private int m_Money;public 小张()
    {
    Console.WriteLine("生成小张....");
    m_Money = 1000; // 构造函数,初始化小张的钱。
    }public int 钱 // 此属性可以操作小张的钱。
    {
    get
    {
    return m_Money;
    }
    set
    {
    m_Money = value;
    }
    }public void 玩游戏()
    {
    Console.WriteLine("小张开始玩游戏了.....");
    Console.WriteLine("小张:CS好玩,哈哈哈! 我玩.....");
    System.Threading.Thread.Sleep(500);
    System.EventArgs e = new EventArgs();
    OnPlayGame(e);
    }protected virtual void OnPlayGame(EventArgs e)
    {
    if(PlayGame != null)
    {
    PlayGame(this,e);
    }
    }
    }// 定义委托处理程序
    public delegate void PlayGameHandler(object sender,System.EventArgs e);} 
     
      

  5.   

    在.net 编程环境中,系统的资源分为托管资源和非托管资源。 
    对于托管的资源的回收工作,是不需要人工干预回收的,而且你也无法干预他们的回收,所能够做的只是了解.net CLR如何做这些操作。也就是说对于您的应用程序创建的大多数对象,可以依靠 .NET Framework 的垃圾回收器隐式地执行所有必要的内存管理任务。 对于非托管资源,您在应用程序中使用完这些非托管资源之后,必须显示的释放他们,例如System.IO.StreamReader的一个文件对象,必须显示的调用对象的Close()方法关闭它,否则会占用系统的内存和资源,而且可能会出现意想不到的错误。 我想说到这里,一定要清楚什么是托管资源,什么是非托管资源了? 最常见的一类非托管资源就是包装操作系统资源的对象,例如文件,窗口或网络连接,对于这类资源虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。还好.net Framework提供了Finalize()方法,它允许在垃圾回收器回收该类资源时,适当的清理非托管资源。如果在MSDN Library 中搜索Finalize将会发现很多类似的主题,这里列举几种常见的非托管资源:ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader 
    ,Pen,Regex,Socket,StreamWriter,Timer,Tooltip 等等资源。可能在使用的时候很多都没有注意到! 关于托管资源,就不用说了撒,像简单的int,string,float,DateTime等等,.net中超过80%的资源都是托管资源。 非托管资源如何释放,.NET Framework 提供 Object.Finalize 方法,它允许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源。默认情况下,Finalize 方法不执行任何操作。默认情况下,Finalize 方法不执行任何操作。如果您要让垃圾回收器在回收对象的内存之前对对象执行清理操作,您必须在类中重写 Finalize 方法。然而大家都可以发现在实际的编程中根本无法override方法Finalize(),在C#中,可以通过析构函数自动生成 Finalize 方法和对基类的 Finalize 方法的调用。 例如: ~MyClass() { // Perform some cleanup operations here. } 该代码隐式翻译为下面的代码。 protected override void Finalize() { try { // Perform some cleanup operations here. } finally { base.Finalize(); } } 但是,在编程中,并不建议进行override方法Finalize(),因为,实现 Finalize 方法或析构函数对性能可能会有负面影响。一个简单的理由如下:用 Finalize 方法回收对象使用的内存需要至少两次垃圾回收,当垃圾回收器回收时,它只回收没有终结器(Finalize方法)的不可访问的内存,这时他不能回收具有终结器(Finalize方法)的不可以访问的内存。它改为将这些对象的项从终止队列中移除并将他们放置在标记为“准备终止”的对象列表中,该列表中的项指向托管堆中准备被调用其终止代码的对象,下次垃圾回收器进行回收时,就回收并释放了这些内存。
      

  6.   

    NET垃圾回收机制