ฉันควรกำจัด () ชุดข้อมูลและ DataTable หรือไม่


197

ชุดข้อมูลและ DataTable ใช้ทั้ง IDisposable ดังนั้นโดยวิธีปฏิบัติที่ดีที่สุดฉันควรเรียกวิธีการ Dispose () ของพวกเขา

อย่างไรก็ตามจากสิ่งที่ฉันอ่านจนถึงขณะนี้ชุดข้อมูลและ DataTable ไม่มีทรัพยากรที่ไม่มีการจัดการดังนั้น Dispose () ไม่ได้ทำอะไรมากจริงๆ

นอกจากนี้ฉันไม่สามารถใช้using(DataSet myDataSet...)เพราะชุดข้อมูลมีคอลเลกชัน DataTables

ดังนั้นเพื่อความปลอดภัยฉันต้องทำซ้ำผ่าน myDataSet.Tables กำจัดแต่ละ DataTables จากนั้นกำจัด DataSet

ดังนั้นมันจึงคุ้มค่าที่จะโทรหา Dispose () ใน DataSets และ DataTables ของฉันทั้งหมดหรือไม่

ภาคผนวก:

สำหรับผู้ที่คิดว่าควรกำจัดชุดข้อมูล: โดยทั่วไปแล้วรูปแบบการกำจัดคือการใช้งานusingหรือtry..finallyเนื่องจากคุณต้องการรับประกันว่าจะเรียก Dispose ()

อย่างไรก็ตามสิ่งนี้ได้รับความรวดเร็วอย่างน่าเกลียดสำหรับคอลเลกชัน ตัวอย่างเช่นคุณจะทำอย่างไรหากหนึ่งในสายที่จะทิ้ง () โยนข้อยกเว้น? คุณกลืน (ซึ่งเป็น "เลว") เพื่อที่คุณจะสามารถกำจัดองค์ประกอบต่อไปได้หรือไม่

หรือคุณแนะนำให้ฉันโทร myDataSet.Dispose () และลืมเกี่ยวกับการทิ้ง DataTables ใน myDataSet.Tables?


9
การกำจัดไม่ควรโยนข้อยกเว้นใด ๆ ถ้าเป็นเช่นนั้น - มันเขียนไม่ดีดังนั้น ... ลอง {some.Dispose (); } catch {} น่าจะเพียงพอ - blogs.msdn.com/b/clyon/archive/2004/09/23/233464.aspx
LukeSw

3
ฉันสังเกตเห็นว่าหน่วยความจำรั่วอย่างชัดเจนในหนึ่งในแอพของฉันที่ใช้วัตถุชุดข้อมูลจำนวนมาก ฉันไม่ได้โทรหา. ทิ้ง () หรือใช้บล็อค "ใช้" สำหรับวัตถุเหล่านั้น ดังนั้นฉันจึงตรวจสอบรหัสและเพิ่มบล็อก "using" ในทุกที่ที่ฉันสร้างชุดข้อมูลหรือ DataTable และ voila หน่วยความจำจะถูกปล่อยออกมาในขณะนี้ ดูเหมือนว่าสิ่งบ่งชี้ที่ชัดเจนว่า. Dispos () แท้จริงแล้วเป็นสิ่งจำเป็นสำหรับชุดข้อมูลและ DataTable
dizzy.stackoverflow

คำตอบ:


147

นี่คือการอภิปรายสองสามข้อที่อธิบายว่าทำไมการกำจัดไม่จำเป็นสำหรับชุดข้อมูล

เพื่อกำจัดหรือไม่กำจัด? :

กระบวนการกำจัดในชุดข้อมูลมีอยู่เพียงเพราะผลข้างเคียงของการสืบทอด - กล่าวอีกนัยหนึ่งมันไม่ได้ทำอะไรที่มีประโยชน์ในการสรุป

ควรทิ้งถูกเรียกบนวัตถุ DataTable และ DataSet? รวมถึงคำอธิบายจาก MVP:

system.data เนมสเปซ (ADONET) ไม่มีทรัพยากรที่ไม่ได้รับการจัดการ ดังนั้นจึงไม่จำเป็นต้องกำจัดสิ่งเหล่านี้ตราบใดที่คุณยังไม่ได้เพิ่มสิ่งที่พิเศษลงไป

ทำความเข้าใจกับวิธีการกำจัดและชุดข้อมูลหรือไม่ มีความคิดเห็นจากผู้มีอำนาจก็อตต์อัลเลน:

ในการปฏิบัติเราไม่ค่อยกำจัดชุดข้อมูลเพราะให้ประโยชน์เพียงเล็กน้อย "

ดังนั้นฉันทามติที่มีอยู่ในขณะนี้จึงไม่มีเหตุผลที่ดีที่จะเรียกใช้ Dispose บนชุดข้อมูล


7
ลิงก์ที่ให้ไว้พลาดจุดที่ DataTable เป็นวัตถุประเภทหนึ่ง โปรดดูคำตอบของ Nariman ด้านล่าง
เฮอร์แมน

คำตอบที่น่าสนใจ แต่สิ่งที่เกี่ยวกับ SqlConnection, SqlCommand และ SqlDataAdapter ควร Dispose อย่างชัดเจน?
Willy

@Willy ฉันคิดว่าผู้คนจำนวนมากใช้ข้อความสั่งการใช้ IDisposables using (SqlConnection cn = SqlConnection ใหม่ (connectionString)) {using (SqlCommand cm = new SqlCommand (commandString, cn)) {cn.Open (); cm.ExecuteNonQuery (); }}
DOK

1
@Willy ใช่ควรกำจัดเหล่านั้นเพราะใช้ทรัพยากรที่ไม่มีการจัดการ ไม่ว่าจะเรียกว่าอย่างชัดเจนหรือโดยปริยายโดยใช้usingบล็อกขึ้นอยู่กับคุณ
D Stanley

129

อัปเดต (1 ธันวาคม 2009):

ฉันต้องการแก้ไขคำตอบนี้และยอมรับว่าคำตอบเดิมนั้นมีข้อบกพร่อง

การวิเคราะห์เริ่มต้นจะนำไปใช้กับวัตถุที่ต้องการการสรุปและประเด็นที่การปฏิบัติไม่ควรได้รับการยอมรับบนพื้นผิวโดยปราศจากความเข้าใจที่ถูกต้องและลึกซึ้งยังคงมีอยู่

อย่างไรก็ตามปรากฎว่าชุดข้อมูล, DataViews, DataTables ระงับการสรุปในตัวสร้างของพวกเขา - นี่คือเหตุผลที่เรียก Dispose () พวกเขาทำอะไรอย่างชัดเจน

สันนิษฐานว่าเกิดขึ้นเพราะพวกเขาไม่มีทรัพยากรที่ไม่มีการจัดการ ดังนั้นแม้จะมีข้อเท็จจริงที่ว่าMarshalByValueComponentทำเงินสำรองสำหรับทรัพยากรที่ไม่มีการจัดการ แต่การใช้งานเฉพาะเหล่านี้ไม่มีความจำเป็นและสามารถยกเลิกได้

(ผู้เขียน. NET นั้นจะต้องระมัดระวังในการระงับการสรุปในประเภทที่ตามปกติแล้วหน่วยความจำส่วนใหญ่พูดถึงความสำคัญของการปฏิบัตินี้โดยทั่วไปสำหรับประเภทที่สรุปได้)

อย่างไรก็ตามรายละเอียดเหล่านี้ยังไม่ได้รับการจัดทำเอกสารตั้งแต่เริ่มต้นของ. NET Framework (เกือบ 8 ปีที่แล้ว) เป็นเรื่องที่ค่อนข้างน่าแปลกใจ (คุณต้องทิ้งอุปกรณ์ไว้กับตัวเองเพื่อร่อนแม้ว่าวัสดุที่ขัดแย้งกันจะคลุมเครือ บางครั้งก็น่าหงุดหงิด แต่ให้ความเข้าใจที่สมบูรณ์ยิ่งขึ้นเกี่ยวกับกรอบที่เราพึ่งพาทุกวัน)

หลังจากอ่านจำนวนมากนี่คือความเข้าใจของฉัน:

หากวัตถุนั้นต้องการการสรุปมันสามารถครอบครองหน่วยความจำได้นานกว่าที่ต้องการ - นี่คือสาเหตุ: a) ชนิดใด ๆ ที่กำหนด destructor (หรือสืบทอดจากชนิดที่กำหนด destructor) จะถือว่าเป็นวัตถุสุดท้าย b) ในการจัดสรร (ก่อนที่ Constructor จะรัน) ตัวชี้จะถูกวางไว้ในคิว Finalization c) วัตถุที่สามารถทำให้สำเร็จได้โดยปกติจะต้องเรียกคืน2 คอลเลกชัน (แทนที่จะเป็นมาตรฐาน 1) d) การระงับการสรุปไม่ลบวัตถุออกจากคิวการสรุป (ตามที่รายงานโดย! FinalizeQueue ใน SOS) คำสั่งนี้ทำให้เข้าใจผิด; การรู้ว่าวัตถุใดที่อยู่ในคิวการสรุป (ในและของตัวเอง) ไม่มีประโยชน์ การรู้ว่าวัตถุใดที่อยู่ในคิวการสรุปและยังคงต้องการการสรุปจะมีประโยชน์ (มีคำสั่งสำหรับสิ่งนี้หรือไม่)

การระงับการสรุปจะปิดสักเล็กน้อยในส่วนหัวของวัตถุซึ่งระบุถึงรันไทม์ที่ไม่จำเป็นต้องเรียกใช้ Finalizer (ไม่จำเป็นต้องย้ายคิว FReachable) มันยังคงอยู่ในคิวการสรุป (และยังคงถูกรายงานโดย! FinalizeQueue ใน SOS)

คลาส DataTable, DataSet, DataView จะถูกรูททั้งหมดที่ MarshalByValueComponent ซึ่งเป็นออบเจ็กต์สุดท้ายที่สามารถ (อาจ) จัดการกับทรัพยากรที่ไม่มีการจัดการ

  • เนื่องจาก DataTable, DataSet, DataView ไม่แนะนำทรัพยากรที่ไม่ได้รับการจัดการจึงหยุดการสรุปในตัวสร้างของพวกเขา
  • ขณะนี้เป็นรูปแบบที่ผิดปกติมันช่วยให้ผู้โทรไม่ต้องกังวลเกี่ยวกับการโทรทิ้งหลังจากใช้งาน
  • สิ่งนี้และความจริงที่ว่า DataTables สามารถแชร์ข้าม DataSets ต่าง ๆ ได้นั้นเป็นไปได้ว่าทำไม DataSets ไม่สนใจทิ้ง DataTables ย่อย
  • นอกจากนี้ยังหมายความว่าวัตถุเหล่านี้จะปรากฏภายใต้! FinalizeQueue ใน SOS
  • อย่างไรก็ตามวัตถุเหล่านี้ยังคงสามารถเรียกคืนได้หลังจากการรวบรวมเดี่ยวเช่นคู่ที่ไม่สามารถสรุปได้

4 (การอ้างอิงใหม่):

คำตอบเดิม:

มีคำตอบที่เข้าใจผิดและโดยทั่วไปแย่มาก - ผู้ที่ลงจอดที่นี่ควรเพิกเฉยต่อเสียงรบกวนและอ่านข้อมูลอ้างอิงด้านล่างอย่างระมัดระวัง

ไม่ต้องสงสัยเลยว่า Dispose ควรถูกเรียกใช้บนวัตถุใด ๆ

DataTables มี Finalizable

การโทรทิ้งความเร็วในการเรียกคืนหน่วยความจำอย่างมีนัยสำคัญ

MarshalByValueComponentเรียกGC.SuppressFinalize (นี่)ใน Dispose () - ข้ามวิธีนี้ต้องรอนับสิบถ้าไม่ได้รวบรวมคอลเลกชั่น Gen0 หลายร้อยก่อนที่หน่วยความจำจะถูกเรียกคืน:

ด้วยความเข้าใจพื้นฐานของการสรุปเราสามารถสรุปสิ่งสำคัญบางอย่างได้แล้ว:

ก่อนวัตถุที่ต้องการการสรุปจะมีอายุการใช้งานยาวนานกว่าวัตถุที่ไม่ต้องการ ในความเป็นจริงพวกเขาสามารถมีชีวิตอยู่ได้นานขึ้น ตัวอย่างเช่นสมมติว่าวัตถุที่อยู่ใน gen2 ต้องได้รับการสรุป การสรุปจะกำหนดไว้ แต่วัตถุยังอยู่ใน gen2 ดังนั้นมันจะไม่ถูกรวบรวมใหม่จนกว่าจะมีการรวบรวม gen2 ครั้งต่อไป นั่นอาจเป็นเวลาที่นานมากและในความเป็นจริงถ้าสิ่งต่าง ๆ ดีขึ้นมันจะใช้เวลานานเพราะคอลเลคชั่น gen2 มีราคาแพงและเราต้องการให้พวกเขาเกิดขึ้นไม่บ่อยนัก วัตถุที่เก่ากว่าที่ต้องการการสรุปอาจต้องรอนับสิบ ๆ ครั้งหากไม่ใช่คอลเลกชัน gen0 หลายร้อยรายการก่อนที่จะมีการเรียกคืนพื้นที่ของตน

ประการที่สองวัตถุที่ต้องการการสรุปทำให้เกิดความเสียหายต่อหลักประกัน เนื่องจากพอยน์เตอร์ของวัตถุภายในจะต้องถูกต้องไม่เพียง แต่วัตถุที่ต้องการการสรุปขั้นสุดท้ายในหน่วยความจำเท่านั้น แต่ทุกอย่างที่วัตถุอ้างถึงโดยตรงและโดยอ้อมจะยังคงอยู่ในหน่วยความจำ ถ้าต้นไม้ขนาดใหญ่ของวัตถุถูกยึดโดยวัตถุเดียวที่จำเป็นต้องมีการสรุปแล้วต้นไม้ทั้งหมดจะคงอยู่อาจเป็นเวลานานเมื่อเราเพิ่งพูดคุย ดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องใช้ finalizers อย่างประหยัดและวางลงบนวัตถุที่มีตัวชี้วัตถุภายในน้อยที่สุดเท่าที่จะทำได้ ในตัวอย่างต้นไม้ที่ฉันเพิ่งให้คุณสามารถหลีกเลี่ยงปัญหาได้อย่างง่ายดายโดยการย้ายทรัพยากรที่ต้องการการสรุปไปยังวัตถุแยกต่างหากและทำการอ้างอิงถึงวัตถุนั้นในรากของต้นไม้

ในที่สุดวัตถุที่ต้องการการสรุปจะสร้างงานสำหรับเธรด finalizer หากกระบวนการสรุปของคุณเป็นกระบวนการที่ซับซ้อนเธรด finalizer เพียงรายการเดียวเท่านั้นที่จะใช้เวลาส่วนใหญ่ในการดำเนินการตามขั้นตอนเหล่านี้ซึ่งอาจทำให้งานในมือค้างและทำให้วัตถุอื่น ๆ รอการสรุป ดังนั้นจึงเป็นสิ่งสำคัญอย่างยิ่งที่ผู้เข้ารอบสุดท้ายทำผลงานได้น้อยที่สุด โปรดจำไว้ว่าแม้ว่าตัวชี้วัตถุทั้งหมดยังคงใช้ได้ในระหว่างการสรุปอาจเป็นกรณีที่ตัวชี้เหล่านั้นนำไปสู่วัตถุที่ได้รับการสรุปแล้วและอาจมีประโยชน์น้อยกว่า โดยทั่วไปจะปลอดภัยที่สุดในการหลีกเลี่ยงการติดตามตัวชี้วัตถุในรหัสการสรุปแม้ว่าตัวชี้จะถูกต้อง เส้นทางรหัสสรุปสั้น ๆ ที่ปลอดภัยนั้นดีที่สุด

นำมาจากคนที่เห็น DataTables ที่ไม่ใช่อ้างอิงใน 100s MBs ใน Gen2: นี่เป็นสิ่งที่สำคัญอย่างยิ่งและไม่ได้รับคำตอบจากกระทู้นี้

อ้างอิง:

1 - http://msdn.microsoft.com/en-us/library/ms973837.aspx

2 - http://vineetgupta.spaces.live.com/blog/cns!8DE4BDC896BEE1AD!1104.entry http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-garbage -collector ประสิทธิภาพโดยใช้-finalizedispose-pattern.aspx

3 - http://codeidol.com/csharp/net-framework/Inside-the-CLR/Automatic-Memory-Management/


จุดดี. โดยปกติคุณจะจัดโครงสร้างรหัสของคุณอย่างไรเมื่อคุณมีชุดข้อมูลที่มี DataTables จำนวนมาก ตันซ้อนกันโดยใช้คำสั่ง? ลองครั้งเดียว .. ในที่สุดการทำความสะอาดมันทั้งหมดในครั้งเดียว?
mbeckish

14
คำสั่ง "อย่างไรก็ตามปรากฎว่าชุดข้อมูล, DataViews, DataTables ระงับการสรุปในตัวสร้างของพวกเขา - นี่คือเหตุผลที่เรียก Dipose () พวกเขาอย่างชัดเจนไม่ได้ทำอะไรเลย" เป็น non-sequitur: แนวคิดทั้งสองส่วนใหญ่ไม่เกี่ยวข้องกัน สิ่งที่ระงับการสรุปยังสามารถทำอะไรบางอย่างในการกำจัด () อันที่จริงแล้วมันมีเหตุผลมากกว่าถ้าเราย้อนกลับ: Dispose () ไม่ทำอะไรเลยซึ่งเป็นสาเหตุที่ทำให้มันไม่สามารถสรุปได้ใน Constructor นั่นคือเนื่องจากไม่มีสิ่งใดที่จะต้องทำ ซึ่งโดยทั่วไปเรียกว่าการกำจัด)
Marc Gravell

ขอบคุณ การสนทนานี้นำไปใช้กับTableAdapters เช่นกัน?
Bondolin


24

คุณควรถือว่ามันมีประโยชน์และมีการโทรออกแม้ว่าจะไม่ได้ทำอะไรเลยในปัจจุบัน . NET Framework incarnations ไม่มีการรับประกันว่าจะเป็นเช่นนั้นในเวอร์ชันต่อ ๆ ไปซึ่งนำไปสู่การใช้ทรัพยากรที่ไม่มีประสิทธิภาพ


ไม่มีการรับประกันว่าจะใช้ IDisposable ในอนาคตเช่นกัน ฉันจะเห็นด้วยกับคุณถ้ามันง่ายเหมือนการใช้ (... ) แต่ในกรณีของชุดข้อมูลดูเหมือนว่าไม่ยุ่งยากอะไรมาก
mbeckish

28
มันค่อนข้างปลอดภัยที่จะสมมติว่ามันจะใช้ IDisposable การเพิ่มหรือลบส่วนต่อประสานนั้นเป็นการเปลี่ยนแปลงที่ไม่ได้ผลในขณะที่การเปลี่ยนการใช้งานการกำจัดนั้นไม่ใช่
Greg Dean

5
นอกจากนี้ผู้ให้บริการรายอื่นอาจมีการนำไปใช้งานซึ่งทำบางสิ่งด้วย IDisposable
Matt Spradley

ไม่พูดถึงที่DataTableไม่ได้ปิดผนึก - ไม่ใช่เรื่องใหญ่เมื่อคุณทำnew DataTableแต่ค่อนข้างสำคัญเมื่อทำการDataTableโต้แย้งหรือเป็นผลจากการโทรวิธี
Luaan

17

แม้ว่าวัตถุนั้นไม่มีทรัพยากรที่ไม่มีการจัดการการทิ้งอาจช่วย GC โดยการทำลายกราฟวัตถุ โดยทั่วไปถ้าวัตถุใช้ IDisposable แล้ว Dispose () ควรถูกเรียก

ว่า Dispose () ทำอะไรจริงหรือไม่ขึ้นอยู่กับชั้นเรียนที่ให้ ในกรณีของชุดข้อมูลการใช้งาน Dispose () นั้นสืบทอดมาจาก MarshalByValueComponent มันลบตัวเองจากภาชนะและเรียกเหตุการณ์ที่จำหน่าย ซอร์สโค้ดอยู่ด้านล่าง (ถอดออกด้วย. NET Reflector):

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        lock (this)
        {
            if ((this.site != null) && (this.site.Container != null))
            {
                this.site.Container.Remove(this);
            }
            if (this.events != null)
            {
                EventHandler handler = (EventHandler) this.events[EventDisposed];
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            }
        }
    }
}

1
จริง ฉันเห็นรหัสบางส่วนเมื่อเร็ว ๆ นี้ที่ DataTables จำนวนมากถูกสร้างขึ้นในลูปขนาดใหญ่มากโดยไม่ถูกกำจัด สิ่งนี้นำไปสู่การใช้หน่วยความจำทั้งหมดในคอมพิวเตอร์และกระบวนการขัดข้องเมื่อหน่วยความจำหมด หลังจากที่ฉันบอกให้ผู้พัฒนาโทรไปขาย DataTable ปัญหาก็หายไป
RichardOD

7

คุณสร้าง DataTables ด้วยตัวคุณเองหรือไม่? เนื่องจากการวนซ้ำผ่านลูก ๆ ของวัตถุใด ๆ (เช่นเดียวกับใน DataSet.Tables) มักไม่จำเป็นเนื่องจากเป็นหน้าที่ของผู้ปกครองในการกำจัดสมาชิกลูกทั้งหมดของมัน

โดยทั่วไปแล้วกฎคือ: ถ้าคุณสร้างขึ้นมาและใช้ IDisposable ให้กำจัดทิ้ง หากคุณไม่ได้สร้างมันขึ้นมาอย่ากำจัดทิ้งนั่นเป็นหน้าที่ของวัตถุหลัก แต่แต่ละวัตถุอาจมีกฎพิเศษให้ตรวจสอบเอกสาร

สำหรับ. net 3.5 จะระบุว่า "ทิ้งเมื่อไม่ได้ใช้อีกต่อไป" อย่างชัดเจนดังนั้นนั่นคือสิ่งที่ฉันจะทำ


4
จากสิ่งที่ฉันเข้าใจฉันทามติทั่วไปคือวัตถุควรกำจัดทรัพยากรที่ไม่มีการจัดการของตัวเอง อย่างไรก็ตามคอลเลกชันของวัตถุ IDisposable จะไม่ซ้ำโดยทั่วไปผ่านองค์ประกอบเพื่อกำจัดแต่ละรายการเนื่องจากอาจมีการอ้างอิงอื่น ๆ ไปยังองค์ประกอบนอกคอลเลกชัน: stackoverflow.com/questions/496722/ …
mbeckish

1
จริงคอลเลคชั่นเป็นสิ่งที่ฉันคิดว่าพิเศษเสมอเพราะพวกเขามักจะไม่ "ทำอะไร" มันเป็นแค่ ... ภาชนะบรรจุดังนั้นฉันจึงไม่เคยใส่ใจเรื่องนั้น
Michael Stum

7

ฉันเรียกทิ้งเมื่อใดก็ตามที่วัตถุใช้ IDisposeable มันมีเหตุผล

ชุดข้อมูลสามารถ hogs หน่วยความจำขนาดใหญ่ ยิ่งพวกเขาสามารถทำเครื่องหมายสำหรับการทำความสะอาดได้เร็วเท่าไหร่ก็จะยิ่งดีเท่านั้น

ปรับปรุง

5 ปีแล้วที่ฉันตอบคำถามนี้ ฉันยังเห็นด้วยกับคำตอบของฉัน หากมีวิธีการกำจัดมันควรจะเรียกว่าเมื่อคุณทำกับวัตถุ มีการใช้อินเทอร์เฟซ IDispose ด้วยเหตุผล


5
การโทรทิ้งไม่ได้เพิ่มความเร็วในการเรียกคืนหน่วยความจำเพื่อที่คุณจะต้องเริ่มต้นตัวรวบรวมขยะด้วยตนเองซึ่งโดยทั่วไปจะเป็นแผนไม่ดี
Tetraneutron

2
หากการทิ้งตั้งค่าการอ้างอิงจำนวนมากเป็นโมฆะมันสามารถทำให้วัตถุเป็นตัวเลือกสำหรับการรวบรวมที่อาจข้ามไป
Greg Dean

1
จุดประสงค์ของการกำจัดไม่ใช่เพื่อกำจัดความทรงจำของวัตถุที่มีการจัดการนั่นคืองานของตัวเก็บขยะ จุดคือการล้างวัตถุที่ไม่มีการจัดการ ดูเหมือนว่าจะมีหลักฐานว่าชุดข้อมูลไม่มีการอ้างอิงใด ๆ ที่ไม่มีการจัดการดังนั้นในทางทฤษฎีจึงไม่จำเป็นต้องทิ้งชื่อเหล่านั้น ที่ถูกกล่าวว่าฉันไม่เคยอยู่ในสถานการณ์ที่ฉันต้องออกไปเรียก Dispose - ฉันจะเรียกมันว่าต่อไป
cbp

4
การใช้หลักของ IDisposable คือการปล่อยทรัพยากรที่ไม่มีการจัดการ บ่อยครั้งที่มันยังแก้ไขสถานะในลักษณะที่เหมาะสมสำหรับอินสแตนซ์ที่ขายทิ้ง (คุณสมบัติเช่นตั้งค่าเป็นเท็จอ้างอิงตั้งค่าเป็นโมฆะ, ฯลฯ )
เกร็กคณบดี

3
หากมีวิธีการกำจัดบนวัตถุมันจะถูกวางไว้ที่นั่นด้วยเหตุผลไม่ว่าจะเป็นการล้างวัตถุที่ไม่มีการจัดการหรือไม่
Chuck Conway

4

หากความตั้งใจของคุณหรือบริบทของคำถามนี้คือการรวบรวมขยะจริงๆคุณสามารถตั้งค่าชุดข้อมูลและชุดข้อมูลเป็นโมฆะอย่างชัดเจนหรือใช้คำหลักที่ใช้และปล่อยให้พวกเขาออกไปนอกขอบเขต การกำจัดไม่ได้ทำมากเหมือน Tetraneutron กล่าวก่อนหน้านี้ GC จะรวบรวมวัตถุชุดข้อมูลที่ไม่ได้อ้างอิงอีกต่อไปและรวมถึงวัตถุที่อยู่นอกขอบเขต

ฉันต้องการให้ผู้คนถูกบังคับให้ลงคะแนนเพื่อเขียนความคิดเห็นจริง ๆ ก่อนที่จะลดคำตอบลง


+ 1 ฉันคิดว่าบางคนไม่ต้องการให้คนอื่นพิจารณามุมมองที่แตกต่างกัน
DOK

2
การลงคะแนนไม่ว่าใครจะไม่เห็นด้วยกับมุมมองที่แตกต่าง
เกร็กคณบดี

1

ชุดข้อมูลใช้ IDisposable อย่างละเอียด MarshalByValueComponent ซึ่งใช้ IDisposable เนื่องจากชุดข้อมูลได้รับการจัดการจึงไม่มีประโยชน์อย่างแท้จริงในการโทรออก


6
ตอนนี้อาจทราบแล้วว่าใครจะทำอะไรในภายหลัง
Greg Dean

ทัศนคติที่คุณคาดเดาว่ารหัสใด ๆ จะไม่ทำในอนาคตในสิ่งที่ควรทำคือความเจ็บปวดในสมมติฐานสำหรับทุกคนที่เกี่ยวข้อง
MicroservicesOnDDD

0

ลองใช้ฟังก์ชั่น Clear () มันใช้งานได้ดีสำหรับฉันสำหรับการกำจัด

DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();

0

ไม่จำเป็นต้องกำจัด () เนื่องจากชุดข้อมูลสืบทอดคลาส MarshalByValueComponent และ MarshalByValueComponent ใช้ส่วนต่อประสาน IDisposable

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.