• Disposal and Garbage Collection(资源释放处理与垃圾回收)


    来源地址:http://www.albahari.com/nutshell/cs4ch12.aspx

    Calling Dispose from a finalizer(采用完成执行后的释放,也就是析构函数):

    class Test : IDisposable
    {
    public void Dispose() // NOT virtual(非虚函数)
    {
    Dispose (true);
    GC.SuppressFinalize (this); // Prevent finalizer from running.(在执行过程中防止调用最终的资源释放函数)
    }

    protected virtual void Dispose (bool disposing)
    {
    if (disposing)
    {
    // Call Dispose() on other objects owned by this instance(通过其它(类)对象的当前实例调用Dispose() 函数).
    // You can reference other finalizable objects here.(你可以在这里引用其它对象的终结方法)
    // ...
    }

    // Release unmanaged resources owned by (just) this object.(在当前的对象(类)中释放其非托管资源)
    // ...
    }

    ˜Test()
    {
    Dispose (false);
    }
    }

    Resurrection - deleting temporary file(采用析构函数的方式激活删除临时文件的方法)

    public class TempFileRef
    {
    public readonly string FilePath;
    public TempFileRef (string filePath) { FilePath = filePath; }

    ~TempFileRef() { File.Delete (FilePath); }
    }

    Better solution(更好的解决方案):

    public class TempFileRef
    {
    static ConcurrentQueue<TempFileRef> _failedDeletions
    = new ConcurrentQueue<TempFileRef>();

    public readonly string FilePath;
    public Exception DeletionError { get; private set; }

    public TempFileRef (string filePath) { FilePath = filePath; }

    ~TempFileRef()
    {
    try { File.Delete (FilePath); }
    catch (Exception ex)
    {
    DeletionError = ex;
    _failedDeletions.Enqueue (this); // Resurrection
    }
    }
    }

    GC.ReRegisterForFinalize(这是垃圾回收(类)对象的一个静态方法)

    public class TempFileRef
    {
    public readonly string FilePath;
    int _deleteAttempt;

    public TempFileRef (string filePath) { FilePath = filePath; }

    ~TempFileRef()
    {
    try { File.Delete (FilePath); }
    catch
    {
    if (_deleteAttempt++ < 3) GC.ReRegisterForFinalize (this);
    }
    }
    }

    Managed Memory Leak(托管堆的内在泄漏)

    class Host
    {
    public event EventHandler Click;
    }

    class Client
    {
    Host _host;
    public Client (Host host)
    {
    _host = host;
    _host.Click += HostClicked;
    }

    void HostClicked (object sender, EventArgs e) { ... }
    }

    class Test
    {
    static Host _host = new Host();

    public static void CreateClients()
    {
    Client[] clients = Enumerable.Range (0, 1000)
    .Select (i => new Client (_host))
    .ToArray();

    // Do something with clients ... (对客户端做一些操作)
    }
    }

    Timers and memory leaks(时间对象与内在的泄漏)

    using System.Timers;

    class Foo
    {
    Timer _timer;

    Foo()
    {
    _timer = new System.Timers.Timer { Interval = 1000 };
    _timer.Elapsed += tmr_Elapsed;
    _timer.Start();
    }

    void tmr_Elapsed (object sender, ElapsedEventArgs e) { ... }
    }
    class Foo : IDisposable
    {
    ...
    public void Dispose() { _timer.Dispose(); }
    }
    static void Main()
    {
    var tmr = new System.Threading.Timer (TimerTick, null, 1000, 1000);
    GC.Collect();
    System.Threading.Thread.Sleep (10000); // Wait 10 seconds (线程等待10秒)
    }

    static void TimerTick (object notUsed) { Console.WriteLine ("tick"); }
    using (var tmr = new System.Threading.Timer (TimerTick, null, 1000, 1000))
    {
    GC.Collect();
    System.Threading.Thread.Sleep (10000); // Wait 10 seconds
    }

    Weak references(类型引用:var):

    var sb = new StringBuilder ("this is a test");
    var weak = new WeakReference (sb);
    Console.WriteLine (weak.Target); // This is a test(测试目标对象输出的结果)
    var weak = new WeakReference (new StringBuilder ("weak"));
    Console.WriteLine (weak.Target); // weak(输出弱类型目标对象)
    GC.Collect();
    Console.WriteLine (weak.Target); // (nothing)由于上一行代码执行了垃圾回收,这里的资源已经被释放了
    class Widget
    {
    static List<WeakReference> _allWidgets = new List<WeakReference>();

    public readonly string Name;

    public Widget (string name)
    {
    Name = name;
    _allWidgets.Add (new WeakReference (this));
    }

    public static void ListAllWidgets()
    {
    foreach (WeakReference weak in _allWidgets)
    {
    Widget w = (Widget)weak.Target;
    if (w != null) Console.WriteLine (w.Name);
    }
    }
    }

    Weak references and events(弱类型引用与其事件)

    public class WeakDelegate<TDelegate> where TDelegate : class
    {
    class MethodTarget
    {
    public readonly WeakReference Reference;
    public readonly MethodInfo Method;

    public MethodTarget (Delegate d)
    {
    Reference = new WeakReference (d.Target);
    Method = d.Method;
    }
    }

    List<MethodTarget> _targets = new List<MethodTarget>();

    public WeakDelegate()
    {
    if (!typeof (TDelegate).IsSubclassOf (typeof (Delegate)))
    throw new InvalidOperationException
    ("TDelegate must be a delegate type");
    }

    public void Combine (TDelegate target)
    {
    if (target == null) return;

    foreach (Delegate d in (target as Delegate).GetInvocationList())
    _targets.Add (new MethodTarget (d));
    }

    public void Remove (TDelegate target)
    {
    if (target == null) return;
    foreach (Delegate d in (target as Delegate).GetInvocationList())
    {
    MethodTarget mt = _targets.Find (w =>
    d.Target.Equals (w.Reference.Target) &&
    d.Method.MethodHandle.Equals (w.Method.MethodHandle));

    if (mt != null) _targets.Remove (mt);
    }
    }

    public TDelegate Target
    {
    get
    {
    var deadRefs = new List<MethodTarget>();
    Delegate combinedTarget = null;

    foreach (MethodTarget mt in _targets.ToArray())
    {
    WeakReference target = mt.Reference;
    if (target != null && target.IsAlive)
    {
    var newDelegate = Delegate.CreateDelegate (
    typeof (TDelegate), mt.Reference.Target, mt.Method);

    combinedTarget = Delegate.Combine (combinedTarget, newDelegate);
    }
    else
    deadRefs.Add (mt);
    }

    foreach (MethodTarget mt in deadRefs) // Remove dead references
    _targets.Remove (mt); // from _targets.(移除一些无效的引用对象)

    return combinedTarget as TDelegate;
    }
    set
    {
    _targets.Clear();
    Combine (value);
    }
    }
    }
    public class Foo
    {
    WeakDelegate<EventHandler> _click = new WeakDelegate<EventHandler>();

    public event EventHandler Click
    {
    add { _click.Combine (value); } remove { _click.Remove (value); }
    }

    protected virtual void OnClick (EventArgs e)
    {
    EventHandler target = _click.Target;
    if (target != null) target (this, e);
    }
    }
  • 相关阅读:
    35 点击全图后发现地图“不见了”
    34 文件地理数据库(GDB)变文件夹了怎么办
    33 ArcToolBox学习系列之数据管理工具箱——投影与变换(Projections and Transformations)未完待续……
    32 ArcToolBox学习系列之数据管理工具箱——属性域(Domains)的两种创建及使用方式
    30 ArcGIS 许可管理器常见问题(持续更新中……)
    算法竞赛入门经典 第三章 简要题解
    SCOI2003 字符串折叠 & NEERC2002 Folding 题解
    Vjios 1617 超级教主
    Codeforces Round #652 题解
    Codeforces Round #655 题解
  • 原文地址:https://www.cnblogs.com/magic_evan/p/2384645.html
Copyright © 2020-2023  润新知