前言
合理服用 Lazy<T> 类,可以获得以下两个强大的功效:
1,延迟实例化类,提高应用程序运行效率。 2,实现高效的线程安全的单例。
一,延迟实例化类,提高程序运行效率
对于一个体格庞大、功能繁多的应用程序,启动的时候需要实例化很多对象,以便日后使用。但是有个问题,有些实例化的对象可能一次都不会被用到,那么这个对象的实例化过程就是无效的且是浪费时间的。
.NET 4.0 以后,Lazy<T> 类就可以解决这个问题,在使用到这个类的时候,才回去实例化这个类:
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { Lazy<Nlog> nlog = new Lazy<Nlog>(); //Nlog 是否被创建 Console.WriteLine(nlog.IsValueCreated); nlog.Value.Info("Lazy 测试"); Console.WriteLine(nlog.IsValueCreated); Console.ReadKey(); } } class Nlog { public void Info(string msg) { Console.WriteLine("{0} 已存入 Info",msg); } public void Error(string msg) { Console.WriteLine("{0} 已存入 Error", msg); } } }
执行结果:
二、实现高效的线程安全的单例。
在多线程环境中,最经典的单例模式就是 “两次加锁”。而使用 Lazy<T> ,一次锁都不用加,就是这么强。如下,写一个日志类的单例:
public class Nlog { private Nlog() { //保护类不被外部实例化 } //单例, true 表示适用于多线程 public static Lazy<Nlog> Instance = new Lazy<Nlog>(() => new Nlog(), true); public bool Info(string msg) { Console.WriteLine("{0} 已存入 Info", msg); return true; } public bool Error(string msg) { Console.WriteLine("{0} 已存入 Error", msg); return true; } }
class Program { static void Main(string[] args) { Console.WriteLine("Thread start"); Task.Factory.StartNew(() => { var _nlog = Nlog.Instance; Console.WriteLine(_nlog.IsValueCreated); _nlog.Value.Info("普通信息"); Console.WriteLine(_nlog.IsValueCreated); Console.WriteLine("Thread1 over"); }); Thread.Sleep(100); Console.WriteLine(" "); Task.Factory.StartNew(() => { var _nlog = Nlog.Instance; Console.WriteLine(_nlog.IsValueCreated); _nlog.Value.Error("异常信息"); Console.WriteLine(_nlog.IsValueCreated); Console.WriteLine("Thread2 over"); }); Console.ReadKey(); } }
执行结果:
很明显,两个线程先后使用了 Nlog 类,并且是内存中的同一个对象。