弱引用与弱委托
来源:互联网 发布:win7 64位纯净版 知乎 编辑:程序博客网 时间:2024/04/29 01:37
一、弱引用:
我们设计全局缓存时,使用静态或全局字段来引用某个对象,做到一次创建多次使用。比如:
class Program { private static DataCache _cache; public static DataCache Cache { get { if(_cache == null) _cache = new DataCache(); return _cache; } } static void Main(string[] args) { byte [] ss = new byte[]{1,2,3}; GC.Collect(); Console.WriteLine("GC执行完毕"); Console.Read(); } } class DataCache { private IList<string> datas; }
但这样存在弊端:
- DataCache没频繁使用时,浪费内存空间。
- 由于GC只能回收不可达对象,所以没有办法回收这些资源。
WeakReference出场:即在引用对象的同时仍然允许对该对象进行垃圾回收。
所以我们可以这样设计缓存:
class Program { static WeakReference _cache = new WeakReference(null); public static DataCache Cache { get { DataCache cache = _cache.Target as DataCache; if(cache == null) { cache = new DataCache(); _cache.Target = cache; } return cache; } } static void Main(string[] args) { byte [] ss = new byte[]{1,2,3}; Cache.Test(); Cache.Test(); GC.Collect(); Console.WriteLine("GC执行完毕"); Cache.Test(); Console.Read(); } } class DataCache { private IList<string> datas; ~DataCache() { Console.WriteLine("Destory..."); } public void Test() { Console.WriteLine("Test"); } }
二、弱委托
弱委托解决当委托对象的生命周期足够的长时,导致委托内部持有的强对象不能回收,
比如:
class Program { static void Main(string[] args) { Action<string> sAction = new Action<string>(new ClassTest().Print); sAction("abc"); GC.Collect(); sAction("abc"); } } internal class ClassTest { public void Print(string s) { Console.WriteLine(s); } }
输出结果为:abc abc
为了解决当垃圾回收进行时,委托的对象任然存在,就用到了WeakReference
class Program { static void Main(string[] args) { Action<string> sAction = new Action<string>(new ClassTest().Print); WeakReference weakReference = new WeakReference(new ClassTest()); sAction = (s) => { object o = weakReference.Target; if (o != null) { ((ClassTest)o).Print(s); } }; sAction("def"); GC.Collect(); sAction("def"); } } internal class ClassTest { public void Print(string s) { Console.WriteLine(s); } }
输出结果当然只有一个def了。
CLR var C#中的弱委托:
public abstract class WeakDelegate<TDelegate> where TDelegate : class /* MulticastDelegate */ { // This lightweight private struct puts a compile-time type-safety wrapper around the non-generic WeakReference class private struct WeakReference<T> : IDisposable where T : class { private WeakReference m_weakReference; public WeakReference(T target) { m_weakReference = new WeakReference(target); } public T Target { get { return (T)m_weakReference.Target; } } public void Dispose() { m_weakReference = null; } } private WeakReference<TDelegate> m_weakDelegate; private Action<TDelegate> m_removeDelegateCode; public WeakDelegate(TDelegate @delegate) { var md = (MulticastDelegate)(Object)@delegate; if (md.Target == null) throw new ArgumentException("There is no reason to make a WeakDelegate to a static method."); // Save a WeakReference to the delegate m_weakDelegate = new WeakReference<TDelegate>(@delegate); } public Action<TDelegate> RemoveDelegateCode { set { // Save the delegate that refers to code that knows how to remove the // WeakDelegate object when the non-weak delegate object is GC’d m_removeDelegateCode = value; } } protected TDelegate GetRealDelegate() { // If the real delegate hasn't been GC'd yet, just return it TDelegate realDelegate = m_weakDelegate.Target; if (realDelegate != null) return realDelegate; // The real delegate was GC'd, we don't need our WeakReference to it anymore (it can be GC'd) m_weakDelegate.Dispose(); // Remove the delegate from the chain (if the user told us how) if (m_removeDelegateCode != null) { m_removeDelegateCode(GetDelegate()); m_removeDelegateCode = null; // Let the remove handler delegate be GC'd } return null; // The real delegate was GC'd and can't be called } // All derived classes must return a delegate to a private method matching the TDelegate type public abstract TDelegate GetDelegate(); // Implicit conversion operator to convert a WeakDelegate object to an actual delegate public static implicit operator TDelegate(WeakDelegate<TDelegate> @delegate) { return @delegate.GetDelegate(); } } // This class provides support for the non-generic EventHandler delegate public sealed class WeakEventHandler : WeakDelegate<EventHandler> { public WeakEventHandler(EventHandler @delegate) : base(@delegate) { } /// <summary>Returns a reference to the non-generic EventHandler delegate</summary> public override EventHandler GetDelegate() { return Callback; } // This private method must match the desired delegate’s signature private void Callback(Object sender, EventArgs e) { // If the target hasn't been GC'd invoke it var eh = base.GetRealDelegate(); if (eh != null) eh(sender, e); } } // This WeakDelegate partial class provides support for the generic EventHandler<TEventArgs> delegate public sealed class WeakEventHandler<TEventArgs> : WeakDelegate<EventHandler<TEventArgs>> where TEventArgs : EventArgs { public WeakEventHandler(EventHandler<TEventArgs> @delegate) : base(@delegate) { } /// <summary>Returns a reference to the generic EventHandler<typeparam name="TEventArgs"/> delegate</summary> public override EventHandler<TEventArgs> GetDelegate() { return Callback; } private void Callback(Object sender, TEventArgs e) { // If the target hasn't been GC'd invoke it var eh = base.GetRealDelegate(); if (eh != null) eh(sender, e); } }
- 弱引用与弱委托
- c#委托引用与取消引用注意事项
- 强引用,软引用与弱引用
- 强引用与弱引用
- 强引用与弱引用
- Squirrel文档翻译(弱引用和委托)
- Flex event 强引用与弱引用
- Flex event 强引用与弱引用
- Study Flex《强引用与弱引用》
- 强引用与弱引用(暂存)
- .NET 强引用与弱引用
- Object c强引用与弱引用
- c++弱引用与强引用
- Java中的软引用,强引用与弱引用
- JAVA之强引用,弱引用,软引用 与 JVM
- 弱符号与弱引用
- 强类型与弱类型 强引用与弱引用
- 弱符号与强符号,弱引用与强引用
- iphone ios 编译时需要armv6架构
- Linux kernel 中对于Unicode的支持
- 在Win32程序中显示Dos调试窗口
- 关闭eclipse自动弹出console功能
- 正则表达式IP(IPV4)
- 弱引用与弱委托
- 关于函数可重入与其线程安全之我讨论(二)
- shell 编程快速入门
- OpenCV学习笔记(三十七)——实用函数、系统函数、宏core
- linux----软件包管理、任务计划的安排、添加硬盘、划分磁盘配额、挂载外部设备等
- android AsyncPlayer 后台播放音乐
- Linux下安装python模块时缺少Python.h
- adb与fastboot
- php 获取HTML元素值