配色: 字号:
Net高级技术——IDisposable
2016-08-25 | 阅:  转:  |  分享 
  
Net高级技术——IDisposable



IDisposable概述



GC(垃圾收集器)只能回收托管(Managed)内存资源,对于数据库连接、文件句柄、Socket连接等这些资源(非托管资源,UnManaged)就无能为例,必须程序员自己控制资源的回收。非托管资源:SqlConnection、FileStream等。



对于使用非内存资源的类,完全可以自己定义一个销毁资源的方法来供程序员回收,.net推荐实现IDisposable接口(为了规范非托管资源的回收),在Dispose方法中进行回收。



实现了IDisposable接口的对象都可以使用using进行资源管理。using就是帮我们做了:



复制代码

1FileStreamfs=newF.....

2try{

3fs.read()....

4}

5finally{

6fs.Dispose();

7}

复制代码

实现了IDisposable接口的对象都要进行回收,否则很可能有内存泄露。



非托管内存资源才需要实现IDisposable



IDisposable例子



复制代码

1namespace资源回收

2{

3classProgram

4{

5staticvoidMain(string[]args)

6{

7//使用using对实现IDisposable的类了进行资源管理

8/拿到一个对象的时候,首先判断这个对象是否实现了IDisposable接口,如果实现了,最好就用using包裹住这个对象,保证这个对象用完之后被释放掉,否则很可能出现资源泄露的问题

9/

10using(Telphonet1=newTelphone())

11{

12t1.Open();

13t1.Speak("hello");

14t1.Bomb();

15//t1.Dispose();//如果在这里调用了Dispose()方法释放资源,那么在执行t1.Open()方法就出错,电话线已经被剪断了,无法再打电话了

16t1.Open();

17t1.Speak("Iamback!");

18}//代码执行到这里后,就会调用Dispose方法来进行资源回收

19Console.ReadKey();

20}

21}

22///

23///Telphone类实现了IDisposable接口

24///


25classTelphone:IDisposable

26{

27///

28///电话状态

29///


30privateTelphoneStatestate;

31///

32///打电话

33///


34publicvoidOpen()

35{

36if(state==TelphoneState.Disposed)

37{

38thrownewException("电话线已经被剪断,无法打开!");

39}

40state=TelphoneState.Open;

41Console.WriteLine("拿起电话");

42}

43///

44///说话

45///


46///说话内容

47publicvoidSpeak(strings)

48{

49if(state!=TelphoneState.Open)

50{

51thrownewException("没有连接");

52}

53Console.WriteLine(s);

54}

55///

56///挂掉电话

57///


58publicvoidBomb()

59{

60state=TelphoneState.Close;

61Console.WriteLine("挂掉电话");

62}

63#regionIDisposable成员

64///

65///实现IDisposable接口中的Dispose()方法来释放非托管资源

66///如何释放非托管资源由程序自己定

67///


68publicvoidDispose()

69{

70if(state==TelphoneState.Open)

71{

72Bomb();//挂掉电话

73}

74state=TelphoneState.Disposed;

75Console.WriteLine("剪断电话线");

76}

77#endregion

78}

79///

80///电话状态枚举

81///


82enumTelphoneState

83{

84Open,Close,Disposed

85}

86}

.Net高级技术——结构体



结构体



结构体和类的区别:结构体是值类型,类是引用类型



结构体非常类似于类,但是值类型(拷贝传递),不能被继承



Int32、DateTime等都是结构体,从ValueType继承,值类型。



结构体测试程序:



复制代码

1usingSystem;

2usingSystem.Collections.Generic;

3usingSystem.Linq;

4usingSystem.Text;

5usingSystem.Drawing;

6namespace结构体

7{

8classProgram

9{

10staticvoidMain(string[]args)

11{

12Personp1=newPerson();

13Personp2=p1;

14p1.Age=24;

15p1.Name="孤傲苍狼";

16Console.WriteLine("p1.Name={0},p1.Age={1}",p1.Name,p1.Age);

17Console.WriteLine("p2.Name={0},p2.Age={1}",p2.Name,p2.Age);

18p2.Name="白虎神皇";

19Console.WriteLine("p1.Name={0},p1.Age={1}",p1.Name,p1.Age);

20Console.WriteLine("p2.Name={0},p2.Age={1}",p2.Name,p2.Age);

21Console.WriteLine(object.ReferenceEquals(p1,p2));

22Console.WriteLine(object.Equals(p1,p2));

23Console.WriteLine(www.wang027.com.(p1==p2);

24MyPointpoint1=ReadKeynewMyPoint();

25MyPointpoint2=point1;

26Console.WriteLine(object.ReferenceEquals(point1,point2));//结构体是值类型,拷贝一份,因此point1和point2是两个不同的对象

27point1.X=10;

28point1.Y=20;

29point1.SayHello();

30Console.WriteLine("point1.X={0},point1.Y={1}",point1.X,point1.Y);

31Console.WriteLine("point2.X={0},point2.Y={1}",point2.X,point2.Y);

32Console.ReadKey();

33}

34}

35//结构体非常类似于类,但是值类型(拷贝传递),不能被继承

36//Int32、DateTime等都是结构体,从ValueType继承,值类型。

37///

38///定义结构体

39///


40structMyPoint

41{

42///

43///定义结构体的属性

44///


45publicintX{get;set;}

46///

47///定义结构体的属性

48///


49publicintY{get;set;}

50///

51///定义结构体的方法

52///


53publicvoidSayHello()

54{

55Console.WriteLine("HelloWorld!");

56}

57}

58///

59///定义类

60///


61classPerson

62{

63publicintAge{get;set;}

64publicstringName{get;set;}

65}

66}



Stopwatch的使用



复制代码

1usingSystem;

2usingSystem.Collections.Generic;

3usingSystem.Linq;

4usingSystem.Text;

5usingSystem.Threading.Tasks;

6

7namespaceStopwatch的使用

8{

9classProgram

10{

11

12///

13///使用Stopwatch比较for循环和foreach循环的效率

14///


15///

16staticvoidMain(string[]args)

17{

18

19int[]intArr=newint[1000000];

20for(inti=1;i<=1000000;i++)

21{

22intArr[i-1]=i;

23}

24

25//使用Stopwatch统计程序运行的时间

26/

27Stopwatch提供了几个方法用以控制Stopwatch对象。

28Start方法开始一个计时操作,Stop方法停止计时。

29此时如果第二次使用Start方法,将继续计时,最终的计时结果为两次计时的累加。

30为避免这种情况,在第二次计时前用Reset方法将对象归零。这三个方法都不需要参数

31/

32System.Diagnostics.Stopwatchsw=newSystem.Diagnostics.Stopwatch();

33sw.Start();//开始计时

34

35intsum=0;

36

37for(inti=1;i<=intArr.Length;i++)

38{

39sum+=i;

40}

41Console.WriteLine("sum={0}",sum);

42

43sw.Stop();//停止计时

44longresult=sw.ElapsedMilliseconds;//获得程序运行的时间

45Console.WriteLine("使用for循环计算从1加到1000000的和所需要的时间是:{0}",result);

46

47Console.WriteLine("");

48sw.Reset();

49sw.Start();

50

51sum=0;

52foreach(variteminintArr)

53{

54sum+=item;

55}

56Console.WriteLine("sum={0}",sum);

57Console.WriteLine("使用foreach循环计算从1加到1000000的和所需要的时间是:{0}",sw.ElapsedMilliseconds);

58sw.Stop();

59

60Console.ReadKey();

61}

62}

63}

献花(0)
+1
(本文系thedust79首藏)