แบบฟอร์ม C # ปิดเทียบกับแบบฟอร์มกำจัด


88

ฉันเพิ่งเริ่มใช้ C # และฉันพยายามดูโพสต์ก่อนหน้านี้ แต่ไม่พบคำตอบที่ดี

ใน C # Windows Form Application แบบฟอร์มเดียวใช้Form.Close()ดีกว่าหรือForm.Dispose()?

MSDN กล่าวว่าทรัพยากรทั้งหมดภายในออบเจ็กต์ถูกปิดและฟอร์มจะถูกกำจัดเมื่อมีการเรียกใช้การปิด ซึ่งเป็นแรงบันดาลใจให้ฉันได้พบกับหลายตัวอย่างออนไลน์ซึ่งเป็นไปตาม Dispose แทนที่จะปิด

คนหนึ่งมีข้อได้เปรียบเหนือคนอื่น ๆ หรือไม่? เราควรเลือกสถานการณ์ใดสถานการณ์หนึ่งมากกว่าอีกสถานการณ์หนึ่ง


คำถามที่แตกต่างกันเล็กน้อยคำตอบเดียวกัน IMO: เช่นปิดและขายมักจะเท่ากันยกเว้นว่าคุณสามารถเรียกปิดได้มากกว่าหนึ่งครั้ง
ChrisW

2
@Chrisw: คุณสามารถเรียก Dispose ได้มากกว่าหนึ่งครั้ง
Henk Holterman

@ChrisW, Dispose ควรได้รับการออกแบบให้ทำงานมากกว่าหนึ่งครั้งเช่นกัน bluebytesoftware.com/blog/…
Steven Evers

สิ่งที่ทำให้ฉันปิด === กำจัดแทนที่จะปิด == form.Visible = false; ฉันคาดหวังว่าการปิดจะเป็นวิธีที่นุ่มนวลกว่าการกำจัดทิ้ง
Pete Kirkham

4
@Pete Kirkham: ถ้าคุณต้องการform.Visible = false;สามารถโทรform.Hide(). ในความเป็นจริงเพียงแค่ชุดform.Hide() this.Visible = false;
Dirk Vollmar

คำตอบ:


172

นี้ฟอรั่มใน MSDN จะบอกคุณ

Form.Close()ส่งข้อความ Windows ที่เหมาะสมเพื่อปิดหน้าต่าง win32 ในระหว่างขั้นตอนนั้นหากไม่แสดงแบบฟอร์ม Modally Dispose จะถูกเรียกบนแบบฟอร์ม การกำจัดแบบฟอร์มจะทำให้ทรัพยากรที่ไม่มีการจัดการซึ่งฟอร์มกำลังถืออยู่นั้นเป็นอิสระ

หากคุณทำform1.Show()หรือ Application.Run(new Form1())กำจัดจะถูกเรียกเมื่อClose()ถูกเรียก

อย่างไรก็ตามหากคุณform1.ShowDialog() ต้องการแสดงฟอร์มแบบโมฆะแบบฟอร์มจะไม่ถูกกำจัดทิ้งและคุณจะต้องเรียกform1.Dispose()ตัวเองว่า ฉันเชื่อว่านี่เป็นครั้งเดียวที่คุณควรกังวลเกี่ยวกับการทิ้งแบบฟอร์มด้วยตัวเอง


รุ่นที่ 1 มีใบเสนอราคาหรือไม่ +1 เพื่อชดเชย
Henk Holterman

@ Dan รุ่นแรกดูด ... (ขออภัย @Kyra)
jjnguy

13
สิ่งนี้ค่อนข้างไม่เหมือนกับสถานะ MSDN ที่msdn.microsoft.com/en-us/library/… : "เงื่อนไขเดียวเมื่อไม่ได้กำจัดแบบฟอร์มเมื่อปิดคือเมื่อเป็นส่วนหนึ่งของอินเทอร์เฟซหลายเอกสาร (MDI) แอปพลิเคชันและมองไม่เห็นแบบฟอร์มในกรณีนี้คุณจะต้องเรียก Dispose ด้วยตนเองเพื่อทำเครื่องหมายการควบคุมแบบฟอร์มทั้งหมดสำหรับการรวบรวมขยะ " อย่างไรก็ตามควรตรวจสอบได้ง่ายว่ารูปแบบโมดอลถูกกำจัดหรือไม่ด้วยตัวอย่างง่ายๆ
Dirk Vollmar


15

ตามกฎทั่วไปฉันมักจะสนับสนุนอย่างชัดเจนในการเรียกเมธอด Dispose สำหรับคลาสใด ๆ ที่นำเสนอไม่ว่าจะโดยการเรียกใช้เมธอดโดยตรงหรือการปิดกั้นในบล็อก "ใช้"

ส่วนใหญ่แล้วคลาสที่ใช้ IDisposible จะทำเช่นนั้นเนื่องจากรวมทรัพยากรที่ไม่มีการจัดการบางส่วนที่จำเป็นต้องปล่อยให้เป็นอิสระ ในขณะที่คลาสเหล่านี้ควรมี Finalizers ที่ทำหน้าที่เป็นตัวป้องกันการเรียก Dispose จะช่วยปลดปล่อยหน่วยความจำนั้นก่อนหน้านี้และมีค่าใช้จ่ายที่ต่ำกว่า

ในกรณีของออบเจ็กต์ Form ตามที่ Kyra ระบุไว้เมธอด Close ได้รับการบันทึกไว้เพื่อเรียก Dispose ในนามของคุณดังนั้นคุณไม่จำเป็นต้องทำเช่นนั้นอย่างชัดเจน อย่างไรก็ตามสำหรับฉันแล้วนั่นรู้สึกเหมือนอาศัยรายละเอียดการใช้งานอยู่เสมอ ฉันชอบที่จะเรียกทั้ง Close และ Dispose สำหรับคลาสที่นำไปใช้เพื่อป้องกันการเปลี่ยนแปลง / ข้อผิดพลาดในการนำไปใช้งานและเพื่อความชัดเจน วิธีการกำจัดที่นำไปใช้อย่างถูกต้องควรปลอดภัยในการเรียกใช้หลายครั้ง



6

การไม่โทรCloseอาจเป็นการเลี่ยงการส่งข้อความ Win32 จำนวนมากซึ่งใครจะคิดว่าค่อนข้างสำคัญแม้ว่าฉันจะไม่สามารถบอกคุณได้ว่าทำไม ...

Closeมีประโยชน์ในการยกระดับเหตุการณ์ (ที่สามารถยกเลิกได้) เพื่อให้บุคคลภายนอก (ในแบบฟอร์ม) สามารถเฝ้าดูFormClosingและFormClosedเพื่อตอบสนองตามนั้น

ฉันไม่ชัดเจนว่าFormClosingและ / หรือได้FormClosedรับการเลี้ยงดูถ้าคุณเพียงแค่ทิ้งแบบฟอร์ม แต่ฉันจะปล่อยให้คุณทดลองใช้


3
หากคุณทิ้งแบบฟอร์มจะไม่มีการเรียกเหตุการณ์ปิดและปิด
เมทริกซ์

5
การเรียกเมธอด Dispose จะทำให้หน้าต่างกะพริบเมื่อใช้บน Modal-Form บนหน้าต่าง
mdi


0

ปิด () - ทรัพยากรที่มีการจัดการสามารถปิดชั่วคราวและสามารถเปิดได้อีกครั้ง

Dispose () - ลบทรัพยากรที่มีการจัดการหรือไม่ได้รับการจัดการอย่างถาวร


3
ShowDialog()นี่คือความจริงเฉพาะในกรณีที่รูปแบบถูกนำมาแสดงโดยใช้ มิฉะนั้นClose()จะทิ้งแบบฟอร์มเช่นกัน
Peter Duniho

-1

หากคุณใช้ form.close () ในแบบฟอร์มของคุณและตั้งค่า FormClosing Event ของแบบฟอร์มของคุณและใช้ form.close () ในเหตุการณ์นี้คุณจะตกอยู่ในลูปที่ไม่ จำกัด และอาร์กิวเมนต์นอกช่วงเกิดขึ้นและวิธีแก้ไขก็คือการเปลี่ยนแบบฟอร์ม .close () พร้อม form.dispose () ใน Event of FormClosing หวังว่าเคล็ดลับเล็ก ๆ น้อย ๆ นี้จะช่วยคุณได้ !!!


-1

สิ่งที่ฉันเพิ่งทดลองกับเครื่องมือวินิจฉัย VS ฉันเรียกสิ่งนี้ว่าปิด () จากนั้นจึงเรียกเหตุการณ์แบบฟอร์ม จากนั้นเมื่อฉันเรียกสิ่งนี้ Dispose () ในตอนท้ายในเหตุการณ์ Formclosing ที่ฉันทิ้งวัตถุอื่น ๆ อีกมากมายในนั้นจะทำความสะอาดทุกอย่างได้ราบรื่นขึ้นมาก

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