ต้นฉบับ: http://www.mikel.cn/article.asp?id=1698
คุณรู้จักกลไกการเก็บขยะของ .Net หรือไม่ คุณช่วยอธิบายสั้น ๆ ว่า GC ทำงานอย่างไร? เราจะจัดการหน่วยความจำอย่างมีประสิทธิภาพได้อย่างไร? บทบาทของอ็อบเจ็กต์ที่สร้างอินสแตนซ์ในเนื้อหาของคำสั่ง การใช้ คืออะไร?
ส่วนนี้จัดระเบียบดังนี้ 1. ประเภทเน็ตและการจัดสรรหน่วยความจำ 2. วิธีการทำงานของตัวรวบรวมขยะ GC 3. ทรัพยากรที่ไม่มีการจัดการคืออะไร 4. วิธีปล่อยทรัพยากรอ็อบเจ็กต์อย่างมีประสิทธิภาพ สรุป มาเริ่มศึกษาส่วนนี้กันดีกว่า
1..ประเภทเน็ตและการจัดสรรหน่วยความจำ
ทุกประเภทใน Net ได้มาจากประเภท System.Object (ทางตรงหรือทางอ้อม)
ประเภทใน CTS แบ่งออกเป็นสองประเภท - ประเภทการอ้างอิง (ประเภทอ้างอิงหรือที่เรียกว่าประเภทที่ได้รับการจัดการ) ซึ่งได้รับการจัดสรรบนฮีปหน่วยความจำ และประเภทค่า ประเภทค่าจะถูกจัดสรรบนสแต็ก ตามที่แสดงในภาพ
ประเภทค่าจะอยู่บนสแต็ก เข้าก่อน และออกหลัง ตัวแปรประเภทค่ามีลำดับชีวิต ซึ่งจะทำให้แน่ใจได้ว่าตัวแปรประเภทค่าจะปล่อยทรัพยากรก่อนที่จะถูกผลักออกนอกขอบเขต เรียบง่ายและมีประสิทธิภาพมากกว่าประเภทอ้างอิง สแต็กจัดสรรหน่วยความจำจากที่อยู่สูงไปยังที่อยู่ต่ำ
ประเภทการอ้างอิงได้รับการจัดสรรบนฮีปที่ได้รับการจัดการ (ฮีปที่มีการจัดการ) และตัวแปรจะถูกประกาศและบันทึกไว้ในสแต็ก เมื่อใช้ใหม่เพื่อสร้างออบเจ็กต์ ที่อยู่ของออบเจ็กต์จะถูกจัดเก็บไว้ในตัวแปรนี้ ในทางตรงกันข้าม ฮีปที่ได้รับการจัดการจะจัดสรรหน่วยความจำจากที่อยู่ต่ำไปยังที่อยู่สูง ดังแสดงในรูป
2. พนักงานเก็บขยะ GC ทำงานอย่างไร
ในรูปด้านบน เมื่อชุดข้อมูลหมดอายุ เราจะไม่แสดงการทำลายออบเจ็กต์ และออบเจ็กต์บนฮีปยังคงมีอยู่ เพื่อรอการรีไซเคิล GC
ขอแนะนำแต่ไม่จำเป็นว่าตัวรวบรวมขยะสนับสนุนอายุของอ็อบเจ็กต์จนถึงรุ่น รุ่นคือหน่วยของวัตถุที่มีอายุสัมพันธ์กันในหน่วยความจำ วัตถุ
ชื่อรหัสหรืออายุระบุรุ่นที่มีวัตถุอยู่ ในวงจรชีวิตของแอปพลิเคชัน ออบเจ็กต์ที่สร้างขึ้นเมื่อเร็ว ๆ นี้จะเป็นของคนรุ่นใหม่และมีค่าสูงกว่าออบเจ็กต์ที่สร้างขึ้นก่อนหน้านี้
หมายเลขรหัสย่อยด้านล่าง รหัสวัตถุในรุ่นล่าสุดคือ 0
เมื่อสร้างออบเจ็กต์ใหม่ คุณต้องค้นหารายการลิงก์ฟรีก่อนเพื่อค้นหาบล็อกหน่วยความจำที่เหมาะสมที่สุด จัดสรร ปรับรายการลิงก์บล็อกหน่วยความจำ และรวมแฟรกเมนต์ การดำเนินการใหม่สามารถเสร็จสิ้นได้ในเวลาเกือบ O(1) โดยเพิ่ม 1 ไปที่ตัวชี้ด้านบนของฮีป หลักการทำงานคือ: เมื่อพื้นที่ที่เหลืออยู่บนฮีปที่ได้รับการจัดการไม่เพียงพอ หรือพื้นที่ของ Generator 0 เต็ม GC จะทำงานและเริ่มเรียกคืนหน่วยความจำ ที่จุดเริ่มต้นของการรวบรวมขยะ GC จะบีบอัดและปรับหน่วยความจำฮีป และออบเจ็กต์จะรวมอยู่ที่ด้านบน GC จะใช้เวลา CPU เป็นระยะเวลาหนึ่งเมื่อสแกนขยะ อัลกอริธึม GC ดั้งเดิมจะสแกนฮีปทั้งหมดซึ่งไม่มีประสิทธิภาพ GC ปัจจุบันแบ่งออบเจ็กต์ในฮีปออกเป็นสามรุ่น รายการล่าสุดในฮีปคือรุ่นที่ 0 ตามด้วยรุ่นที่ 1 และรุ่นที่ 2 GC แรกจะสแกนเฉพาะรุ่นที่ 0 หากพื้นที่ยึดเพียงพอต่อการใช้งานในปัจจุบัน ก็ไม่จำเป็นต้องสแกนวัตถุรุ่นอื่น ดังนั้น GC จึงสร้างวัตถุได้อย่างมีประสิทธิภาพมากกว่า C++ และไม่จำเป็นต้องสแกนพื้นที่ฮีปทั้งหมด การปรับปรุงประสิทธิภาพที่เกิดจากกลยุทธ์การสแกนและกลยุทธ์การจัดการหน่วยความจำนั้นเพียงพอที่จะชดเชยเวลา CPU ที่ GC ครอบครอง
3. ทรัพยากรที่ไม่มีการจัดการคืออะไร
ทรัพยากรที่ไม่มีการจัดการทั่วไปคือวัตถุที่ล้อมทรัพยากรระบบปฏิบัติการ เช่น แฟ้ม หน้าต่าง หรือการเชื่อมต่อเครือข่าย สำหรับทรัพยากรดังกล่าว แม้ว่าตัวรวบรวมขยะสามารถติดตามอายุการใช้งานของวัตถุที่ล้อมทรัพยากรที่ไม่มีการจัดการ แต่ก็รู้วิธีที่จะ ทำความสะอาดทรัพยากรเหล่านี้ โชคดีที่เมธอด Finalize() จัดทำโดย .net Framework ช่วยให้ทรัพยากรที่ไม่มีการจัดการได้รับการล้างอย่างเหมาะสม ก่อนที่ตัวรวบรวมขยะจะรีไซเคิลทรัพยากรดังกล่าว ต่อไปนี้เป็นทรัพยากรที่ไม่มีการจัดการทั่วไปหลายประการ: แปรง สตรีมออบเจ็กต์ คอมโพเนนต์ออบเจ็กต์ และทรัพยากรอื่นๆ (Object, OdbcDataReader, OleDBDataReader, Pen, Regex, Socket, StreamWriter, ApplicationContext, Brush,
ส่วนประกอบ, ComponentDesigner, คอนเทนเนอร์, บริบท, เคอร์เซอร์, FileStream,
แบบอักษร, ไอคอน, รูปภาพ, เมทริกซ์, ตัวจับเวลา, เคล็ดลับเครื่องมือ) (อ้างอิงถึง MSDN)
4. วิธีการเผยแพร่ทรัพยากรที่ไม่มีการจัดการอย่างมีประสิทธิภาพ
GC ไม่สามารถจัดการทรัพยากรที่ไม่มีการจัดการได้ แล้วจะปล่อยทรัพยากรที่ไม่มีการจัดการได้อย่างไร .Net มีสองวิธี:
(1) Destructor: เมื่อตัวรวบรวมขยะรีไซเคิลทรัพยากรของอ็อบเจ็กต์ที่ไม่มีการจัดการ มันจะเรียกวิธีการสรุปของอ็อบเจ็กต์ Finalize() เพื่อล้างทรัพยากร อย่างไรก็ตาม เนื่องจากข้อจำกัดของกฎการทำงานของ GC GC จึงเรียกอ็อบเจ็กต์ Finalize วิธีการ ทรัพยากรจะไม่ถูกปล่อยออกมาเพียงครั้งเดียว และวัตถุจะถูกลบหลังจากการเรียกครั้งที่สอง
(2) สืบทอดอินเทอร์เฟซ IDisposable และใช้เมธอด Dispose() อินเทอร์เฟซ IDisposable กำหนดรูปแบบ (พร้อมการสนับสนุนระดับภาษา) ให้กลไกบางอย่างสำหรับการปล่อยทรัพยากรที่ไม่มีการจัดการ และหลีกเลี่ยงปัญหาโดยธรรมชาติกับการรวบรวมขยะของอุปกรณ์ทำลายล้าง -ประเด็นที่เกี่ยวข้อง
เพื่อให้เข้าใจกลไกการเก็บขยะได้ดีขึ้น ฉันจึงเขียนโค้ดบางส่วนเป็นพิเศษและเพิ่มความคิดเห็นโดยละเอียด กำหนดคลาสเดียว FrankClassWithDispose (สืบทอดอินเทอร์เฟซ IDisposable), FrankClassNoFinalize (ไม่มีตัวปิดท้าย), FrankClassWithDestructor (กำหนด destructor)
รหัสเฉพาะมีดังนี้:
รหัส
1 ใช้ระบบ;
2 ใช้ System.Collections.Generic;
3 ใช้ System.Text;
4 ใช้ System.Data;
5 ใช้ System.Data.Odbc;
6 โดยใช้ระบบการวาดภาพ;
7 // เขียนโดย Frank Xu Lei 2/18/2552
8 // ศึกษาการจัดการหน่วยความจำ .NET
9 // คนเก็บขยะ คนเก็บขยะ. ทรัพยากรที่โฮสต์สามารถเรียกคืนได้เมื่อจำเป็นตามนโยบาย
10 // แต่ GC ไม่ทราบวิธีจัดการทรัพยากรที่ไม่มีการจัดการ เช่นการเชื่อมต่อเครือข่าย การเชื่อมต่อฐานข้อมูล แปรง ส่วนประกอบ เป็นต้น
11 //สองกลไกในการแก้ปัญหาการปล่อยทรัพยากรที่ไม่มีการจัดการ ตัวทำลาย, อินเทอร์เฟซ IDispose
12 // จำนวนอ้างอิง COM
13 // การจัดการด้วยตนเอง C++, ลบใหม่
14 // การจัดการอัตโนมัติ VB
15 เนมสเปซการจัดการหน่วยความจำ
16 {
17 // สืบทอดอินเทอร์เฟซ IDisposable ใช้วิธีการ Dispose และปล่อยทรัพยากรอินสแตนซ์ของ FrankClassDispose
18 คลาสสาธารณะ FrankClassWithDispose : IDisposable
19 {
20 OdbcConnection ส่วนตัว _odbcConnection = null;
ยี่สิบเอ็ด
22 // ตัวสร้าง
23 สาธารณะ FrankClassWithDispose()
ยี่สิบสี่ {
25 ถ้า (_odbcConnection == null)
26 _odbcConnection = ใหม่ OdbcConnection();
27 Console.WriteLine( " สร้าง FrankClassWithDispose แล้ว " );
28 }
29 //วิธีทดสอบ
30 โมฆะสาธารณะ DoSomething ()
31 {
32
33 /**/ /// /code ที่นี่เพื่อทำบางสิ่งบางอย่าง
34 กลับ;
35}
36 // Implement Dispose และปล่อยทรัพยากรที่ใช้โดยคลาสนี้
37 โมฆะสาธารณะกำจัด()
38 {
39 ถ้า (_odbcConnection != null )
40 _odbcConnection.ทิ้ง();
41 Console.WriteLine( " FrankClassWithDispose ถูกกำจัด " );
42 }
43}
44 // Finalize ไม่ได้ถูกนำมาใช้ รอให้ GC รีไซเคิลทรัพยากรอินสแตนซ์ของ FrankClassFinalize และรีไซเคิลโดยตรงเมื่อ GC กำลังทำงาน
45 คลาสสาธารณะ FrankClassNoFinalize
46 {
47 OdbcConnection ส่วนตัว _odbcConnection = null ;
48 //คอนสตรัคเตอร์
49 สาธารณะ FrankClassNoFinalize()
50 {
51 ถ้า (_odbcConnection == null)
52 _odbcConnection = ใหม่ OdbcConnection();
53 Console.WriteLine( " สร้าง FrankClassNoFinalize แล้ว " );
54 }
55 //วิธีทดสอบ
56 โมฆะสาธารณะ DoSomething ()
57 {
58
59 // GC.รวบรวม();
60 /**/ /// /code ที่นี่เพื่อทำบางสิ่งบางอย่าง
61 กลับ;
62 }
63}
64 // Implement destructor คอมไพล์ลงในเมธอด Finalize และเรียก destructor ของอ็อบเจ็กต์
65 // เมื่อ GC กำลังทำงานอยู่ ทรัพยากรจะไม่ถูกปล่อยออกมาในการเรียกครั้งแรก แต่เฉพาะในการเรียกครั้งที่สองเท่านั้น
66 //ทรัพยากรอินสแตนซ์ของ FrankClassDestructor
67 // CLR ใช้เธรดอิสระเพื่อดำเนินการวิธีการสรุปของออบเจ็กต์ การเรียกบ่อยครั้งจะทำให้ประสิทธิภาพลดลง
68 คลาสสาธารณะ FrankClassWithDestructor
69 {
70 OdbcConnection ส่วนตัว _odbcConnection = null ;
71 //คอนสตรัคเตอร์
72 สาธารณะ FrankClassWithDestructor()
73 {
74 ถ้า (_odbcConnection == null)
75 _odbcConnection = ใหม่ OdbcConnection();
76 Console.WriteLine( " สร้าง FrankClassWithDestructor แล้ว " );
77 }
78 //วิธีทดสอบ
79 โมฆะสาธารณะ DoSomething()
80 {
81 /***/ /// /code ที่นี่เพื่อทำบางสิ่งบางอย่าง
82
83 กลับ;
84}
85 // Destructor ปล่อยทรัพยากรที่ไม่มีการจัดการ
86 ~ แฟรงค์คลาสพร้อมตัวทำลาย()
87 {
88 ถ้า (_odbcConnection != null )
89 _odbcConnection.ทิ้ง();
90 Console.WriteLine( " FrankClassWithDestructor ถูกกำจัด " );
91 }
92 }
93}
94
มีการใช้อินสแตนซ์ของวัตถุที่ไม่มีการจัดการ OdbcConnection ไคลเอ็นต์ที่สร้างขึ้นได้รับการทดสอบในช่วงสั้นๆ รหัสลูกค้าเป็นดังนี้:
รหัส
1 ใช้ระบบ;
2 ใช้ System.Collections.Generic;
3 ใช้ System.Text;
4 ใช้ System.Data;
5 ใช้การจัดการหน่วยความจำ;
6 // เขียนโดย Frank Xu Lei 2/18/2552
7 // ศึกษาการจัดการหน่วยความจำ .NET
8 // ทดสอบวัตถุที่ไม่มีการจัดการที่ถูกเรียกคืน
9 // ทดสอบโค้ดที่ไม่มีการจัดการ เปรียบเทียบ
10 // สำหรับโค้ดที่ได้รับการจัดการ GC สามารถรีไซเคิลด้วยตัวมันเองอย่างมีกลยุทธ์มากขึ้น หรือสามารถใช้ IDisposable เรียกเมธอด Dispose() แล้วปล่อยมันออกมา
11 เนมสเปซ MemoryManagementClient
12 {
13 โปรแกรมชั้นเรียน
14 {
15 โมฆะคงที่หลัก (สตริง [] args)
16 {
17
18 ///////////////////////////////////////// //(1 ) / //////////////////////////////////////////// //
19 //เรียกเมธอด Dispose() เพื่อปล่อยอย่างแข็งขัน ทรัพยากรความยืดหยุ่น
20 FrankClassWithDispose _frankClassWithDispose = null ;
21 ลอง
ยี่สิบสอง {
23 _frankClassWithDispose = ใหม่ FrankClassWithDispose();
24 _frankClassWithDispose.DoSomething();
25
26}
27 ในที่สุด
28 {
29 ถ้า (_frankClassWithDispose != null )
30 _frankClassWithDispose.ทิ้ง();
31 // Console.WriteLine("อินสแตนซ์ FrankClassWithDispose ได้รับการเผยแพร่แล้ว");
32}
33
34 ///////////////////////////////////////// //(2 ) / /////////////////////////////////////////////// /
35 // คุณสามารถใช้คำสั่ง Making เพื่อสร้างอ็อบเจ็กต์ที่ไม่มีการจัดการได้ ก่อนที่การดำเนินการของเมธอดจะสิ้นสุดลง
36 การใช้ (FrankClassWithDispose _frankClassWithDispose2 = ใหม่ FrankClassWithDispose())
37 {
38 // _frankClassWithDispose2.DoSomething();
39 }
40
41 ///////////////////////////////////////// //(3 ) / //////////////////////////////////////////// //
42 //เมื่อตัวรวบรวมขยะกำลังทำงานอยู่ ทรัพยากรจะถูกปล่อยออกมาหนึ่งครั้ง
43 FrankClassNoFinalize _frankClassNoFinalize = ใหม่ FrankClassNoFinalize();
44 _frankClassNoFinalize.DoSomething();
45
46 /////////////////////////////////////////////// (4) //////////////////////////////////////////////// / /
47 // เมื่อตัวรวบรวมขยะกำลังทำงาน จะใช้เวลาสองครั้งในการปล่อยทรัพยากร
48 FrankClassWithDestructor _frankClassWithDestructor = ใหม่ FrankClassWithDestructor();
49 _frankClassWithDestructor.DoSomething();
50 //////////////////////////////////////////// / (5 ) //////////////////////////////////////////////// /
51 // ไม่สามารถใช้คำสั่งใช้เพื่อสร้างวัตถุได้เนื่องจากไม่ได้ใช้อินเทอร์เฟซ IDispose
52 // การใช้ (FrankClassWithDestructor _frankClassWithDestructor2 = ใหม่ FrankClassWithDestructor())
53 // {
54 // _frankClassWithDestructor2.DoSomething();
55 // }
56
57 /////////////////////////////////////////////// ////////////////////////////////////////////////
58 // สำหรับการแก้ไขข้อบกพร่อง
59 Console.WriteLine( " กดปุ่มใดก็ได้เพื่อดำเนินการต่อ " );
60 คอนโซล ReadLine();
61
62
63}
64}
65 }
66
บางครั้งทรัพยากรต้องได้รับการปล่อยตัวในเวลาที่กำหนด คลาสสามารถใช้อินเทอร์เฟซ IDisposable ที่ดำเนินการจัดการทรัพยากรและวิธีการล้างข้อมูลงาน IDisposable.Dispose
ถ้าผู้เรียกจำเป็นต้องเรียกใช้เมธอด Dispose เพื่อล้างข้อมูลอ็อบเจ็กต์ คลาสจะต้องใช้เมธอด Dispose เป็นส่วนหนึ่งของสัญญา ตัวรวบรวมขยะไม่ได้โทรตามค่าเริ่มต้น
วิธีการกำจัด อย่างไรก็ตาม การใช้วิธีกำจัดสามารถเรียกวิธีการใน GC เพื่อควบคุมพฤติกรรมขั้นสุดท้ายของตัวรวบรวมขยะ
เป็นที่น่าสังเกตว่า: การเรียกเมธอด Dispose() จะเป็นการรีลีสทรัพยากรและมีความยืดหยุ่น คุณสามารถใช้คำสั่ง Making เพื่อสร้างอ็อบเจ็กต์ที่ไม่มีการจัดการได้ ก่อนที่การดำเนินการเมธอดจะสิ้นสุดลง
วิธีการ Dispose() เผยแพร่ทรัพยากร ผลกระทบของปลายทั้งสองด้านของโค้ดจะเหมือนกัน คุณสามารถดู IL ที่คอมไพล์แล้วได้
รหัส
1. ลอง
2 {
3 IL_0003: ไม่
4 IL_0004: อินสแตนซ์ newobj เป็นโมฆะ [MemoryManagement]MemoryManagement.FrankClassWithDispose::.ctor()
5 IL_0009: stloc.0
6 IL_000a: ldloc.0
7 IL_000b: อินสแตนซ์ callvirt เป็นโมฆะ [MemoryManagement]MemoryManagement.FrankClassWithDispose::DoSomething()
8 IL_0010: ไม่
9 IL_0011: ไม่
10 IL_0012: ลาออก IL_0028
11 } // สิ้นสุด .ลอง
12 ในที่สุด
13 {
14 IL_0014: ไม่
15 IL_0015: ldloc.0
16 IL_0016: ldnull
17 IL_0017: CEQ
18 IL_0019: stloc.s CS$ 4 $ 0000
19 IL_001b: ldloc.s CS$ 4 $ 0000
20 IL_001d: brtrue.s IL_0026
21 IL_001f: ldloc.0
22 IL_0020: อินสแตนซ์ callvirt เป็นโมฆะ [MemoryManagement]MemoryManagement.FrankClassWithDispose::Dispose()
23 IL_0025: ไม่
24 IL_0026: ไม่
25 IL_0027: ในที่สุด
26 } // ตัวจัดการสิ้นสุด
27 IL_0028: ไม่
28 IL_0029: อินสแตนซ์ newobj เป็นโมฆะ [MemoryManagement]MemoryManagement.FrankClassWithDispose::.ctor()
29 IL_002e: stloc.1
30. ลอง
31 {
32 IL_002f: ไม่
33 IL_0030: ไม่
34 IL_0031: ลาออก IL_0045
35 } // สิ้นสุด .try
36 ในที่สุด
37 {
38 IL_0033: ldloc.1
39 IL_0034: ldnull
40 IL_0035: CEQ
41 IL_0037: stloc.s CS$ 4 $ 0,000
42 IL_0039: ldloc.s CS$ 4 $ 0,000
43 IL_003b: brtrue.s IL_0044
44 IL_003d: ldloc.1
45 IL_003e: อินสแตนซ์ callvirt เป็นโมฆะ [mscorlib] System.IDisposable::Dispose()
46 IL_0043: ไม่
47 IL_0044: ในที่สุด
48 } // ตัวจัดการสิ้นสุด
49
คำสั่งการใช้มีผลเช่นเดียวกันในการเผยแพร่ทรัพยากรออบเจ็กต์ที่ไม่มีการจัดการ ซึ่งมักพบในการสัมภาษณ์ เช่น การใช้คีย์เวิร์ดคืออะไร และคำถามที่คล้ายกัน คำตอบพื้นฐานในอุดมคติคือ นอกเหนือจากการอ้างอิงเนมสเปซและการตั้งค่านามแฝงสำหรับเนมสเปซแล้ว การใช้งานนี้ยังตระหนักถึงการรีไซเคิลทรัพยากรอ็อบเจ็กต์ที่ไม่มีการจัดการ เช่น การพยายามบล็อกในที่สุด แค่วิธีเขียนง่ายๆ
เมื่อคุณใช้เมธอด Dispose เพื่อนำออกใช้วัตถุที่ไม่มีการจัดการ คุณควรเรียก GC.SuppressFinalize หากวัตถุอยู่ในคิวการสรุปผล GC.SuppressFinalize จะป้องกันไม่ให้ GC เรียกเมธอด Finalize เนื่องจากการเรียกเมธอด Finalize จะทำให้ประสิทธิภาพการทำงานลดลง ถ้าวิธีการกำจัดของคุณได้ล้างข้อมูลทรัพยากรที่ได้รับมอบหมายแล้ว ไม่จำเป็นสำหรับ GC เพื่อเรียกวิธีการสรุป (MSDN) ของวัตถุอีกครั้ง สิ่งที่แนบมาคือรหัส MSDN สำหรับการอ้างอิงของคุณ
รหัส
BaseResource ระดับสาธารณะ: IDisposable
-
//ชี้ไปที่ทรัพยากรที่ไม่มีการจัดการภายนอก
ตัวจัดการ IntPtr ส่วนตัว
// ทรัพยากรที่มีการจัดการอื่น ๆ ที่ใช้โดยคลาสนี้
ส่วนประกอบส่วนตัว ส่วนประกอบ;
// ติดตามว่ามีการเรียกใช้เมธอด .Dispose หรือไม่ ตั้งค่าสถานะบิต ควบคุมพฤติกรรมของตัวรวบรวมขยะ
บูลส่วนตัวถูกกำจัด = false ;
//คอนสตรัคเตอร์
BaseResource สาธารณะ ()
-
// ใส่โค้ด Constructor ที่เหมาะสมที่นี่
-
// ใช้อินเทอร์เฟซ IDisposable
// ไม่สามารถประกาศเป็นวิธีการเสมือนเสมือนได้
// คลาสย่อยไม่สามารถแทนที่วิธีนี้ได้
โมฆะสาธารณะกำจัด ()
-
กำจัด (จริง);
//ออกจากคิวการสรุปผล
// ตั้งค่าโค้ดตัวปิดท้ายการบล็อกของวัตถุ
-
GC.SuppressFinalize( นี่ );
-
// Dispose(bool disposing) จะดำเนินการในสองสถานการณ์ที่แตกต่างกัน
// หากการกำจัดมีค่าเท่ากับ true แสดงว่ามีการเรียกใช้เมธอดแล้ว
// หรือเรียกทางอ้อมด้วยรหัสผู้ใช้ทั้งรหัสที่ได้รับการจัดการและไม่ได้รับการจัดการสามารถปล่อยได้
// ถ้าการกำจัดเท่ากับเท็จ วิธีการนั้นจะถูกเรียกภายในโดยผู้สรุปผล
// คุณไม่สามารถอ้างอิงออบเจ็กต์อื่นได้ แต่สามารถเผยแพร่ได้เฉพาะทรัพยากรที่ไม่มีการจัดการเท่านั้น
การกำจัดโมฆะเสมือนที่ได้รับการป้องกัน (การกำจัดบูล)
-
// ตรวจสอบว่ามีการเรียก Dispose หรือไม่
ถ้า ( ! นี้ .disposed)
-
// หากเท่ากับ true ให้ปล่อยทรัพยากรที่มีการจัดการและไม่ได้รับการจัดการทั้งหมด
ถ้า (ทิ้ง)
-
// ปล่อยทรัพยากรที่ได้รับการจัดการ
ส่วนประกอบทิ้ง();
-
// ปล่อยทรัพยากรที่ไม่มีการจัดการ หากการกำจัดเป็นเท็จ
// เฉพาะโค้ดต่อไปนี้เท่านั้นที่จะถูกดำเนินการ
CloseHandle (ที่จับ);
หมายเลขอ้างอิง = IntPtr.Zero;
// โปรดทราบว่านี่ไม่ปลอดภัยต่อเธรด
// หลังจากรีซอร์สที่ได้รับการจัดการแล้ว เธรดอื่นสามารถเริ่มต้นเพื่อทำลายอ็อบเจ็กต์ได้
// แต่ก่อนที่แฟล็กที่จำหน่ายจะถูกตั้งค่าเป็นจริง
// หากจำเป็นต้องมีความปลอดภัยของเธรด ลูกค้าจะต้องดำเนินการดังกล่าว
-
จำหน่าย = จริง;
-
//ใช้ interop เพื่อเรียกเมธอด
// ล้างทรัพยากรที่ไม่มีการจัดการ
[System.Runtime.InteropServices.DllImport( " Kernel32 " )]
ส่วนตัวภายนอกแบบบูลีน CloseHandle แบบคงที่ (ตัวจัดการ IntPtr);
//ใช้ C# destructor เพื่อใช้โค้ด Finalizer
// สิ่งนี้สามารถเรียกและดำเนินการได้หากไม่ได้เรียกใช้เมธอด Dispose
// หากคุณให้โอกาสคลาสพื้นฐานในการสรุป
// อย่าจัดเตรียม destructor สำหรับคลาสย่อย
~ทรัพยากรฐาน()
-
// อย่าสร้างโค้ดล้างข้อมูลซ้ำ
// เมื่อพิจารณาจากความน่าเชื่อถือและความสามารถในการบำรุงรักษา การเรียก Dispose(false) ถือเป็นวิธีที่ดีที่สุด
กำจัด(เท็จ);
-
// ช่วยให้คุณสามารถเรียกใช้เมธอด Dispose ได้หลายครั้ง
// แต่จะมีข้อยกเว้นเกิดขึ้นหากวัตถุถูกปล่อยออกมา
// ไม่ว่าคุณจะประมวลผลวัตถุเมื่อใด คุณจะตรวจสอบว่าวัตถุนั้นถูกปล่อยออกมาหรือไม่
// ตรวจสอบว่ามันถูกกำจัดแล้วหรือไม่
โมฆะสาธารณะ DoSomething()
-
ถ้า (สิ่งนี้ .disposed)
-
โยน ObjectDisposedException(); ใหม่
-
-
สำหรับประเภทที่การเรียกเมธอด Close เป็นธรรมชาติมากกว่าเมธอด Dispose คุณสามารถเพิ่มเมธอด Close ให้กับคลาสพื้นฐานได้
วิธีการปิดไม่ใช้พารามิเตอร์ และเรียกวิธีการกำจัดที่ดำเนินการล้างข้อมูลที่เหมาะสม
ตัวอย่างต่อไปนี้สาธิตวิธีการปิด
// อย่าตั้งค่าวิธีการเป็นเสมือน
// คลาสที่สืบทอดมาไม่ได้รับอนุญาตให้แทนที่วิธีนี้
โมฆะสาธารณะ ปิด()
-
// เรียกพารามิเตอร์ Dispose โดยไม่มีพารามิเตอร์
กำจัด();
-
โมฆะคงที่สาธารณะ Main()
-
//ใส่โค้ดที่นี่เพื่อสร้าง
// และใช้วัตถุ BaseResource
-