วัตถุที่สร้างโดย IDisposable ที่อ้างอิงถึงผู้สร้างควรกำจัดผู้สร้างนั้นหรือไม่

ฉันมีคลาสที่ใช้ IDisposable ตาม รูปแบบนี้ เพราะ มีการอ้างอิงถึง HttpClient มีลักษณะดังนี้:

public class CustomServiceClient : IDisposable
{
  HttpClient client;

  // ...

  public ServiceCreatedEntity GetEntity()
  {
    // ...
  }

  ~CustomServiceClient()
  {
    this.Dispose(false);
  }

  private bool disposed = false;
  void IDisposable.Dispose()
  {
    if(!disposed)
    {
      this.Dispose(true);
      GC.SuppressFinalize(this);
      disposed = true;
    }
  }

  public void Dispose(bool disposing)
  {
    if(disposing)
    {
      // dispose managed resources
      client.Dispose();
    }

    // dispose unmanaged resources - this class has none
  }
}

public class ServiceCreatedEntity
{
  CustomServiceClient client;

  public ServiceCreatedEntity(CustomServiceClient client)
  {
    this.client = client;
  }

  // some functions that use client
}

ฉันสงสัยว่า ServiceCreatedEntity ควรใช้ IDisposable และกำจัด CustomServiceClient หรือไม่ โดยทั่วไป ฉันคาดว่า CustomServiceClient จะมีอายุการใช้งานยาวนานกว่า ServiceCreatedEntity และฉันกังวลว่าลูกค้าจะกำจัด ServiceCreatedEntity และสับสนว่าทำไม CustomServiceClient ของพวกเขาจึงถูกกำจัดเช่นกัน คำแนะนำใด ๆ ที่จะได้รับการชื่นชมอย่างมาก!


person Andrew Gaspar    schedule 30.06.2014    source แหล่งที่มา
comment
ไม่แน่ใจว่าจะช่วยได้หรือไม่ แต่สิ่งนี้ทำให้ฉันนึกถึงคำถามนี้ TL, DR: StreamReader, StreamWriter, BinaryReader และ BinaryWriter ทั้งหมดจะปิด/กำจัดสตรีมที่ซ่อนอยู่เมื่อคุณเรียกใช้ Dispose ยังเกี่ยวข้องด้วย, TL,DR: ถ้า คุณปล่อย GC ไว้ มันจะเรียก Dispose(false) ซึ่งจะไม่กำจัดกระแสข้อมูลพื้นฐาน .. เพียงเพื่อให้คุณเข้าใจถึงสถานการณ์ที่คล้ายกันใน .NET   -  person tnw    schedule 30.06.2014
comment
@tnw - ฉันคิดเกี่ยวกับเรื่องนั้น ฉันคิดว่าฉันสามารถจัดเตรียมเอกสารให้กับผู้ใช้ของฉันโดยให้คำแนะนำแก่พวกเขาในการกำจัด ServiceCreatedEntity หากพวกเขาจัดการกับไคลเอนต์เสร็จแล้วเช่นกัน แต่ความแตกต่างที่นี่คือ StreamReaders/Writers/etc ถูกสร้างขึ้นอย่างชัดเจนด้วยโอเปอเรเตอร์ใหม่ (RAII และทั้งหมดนั้น) ดังนั้นผู้สร้างจึงถูกคาดหวังให้เป็นเจ้าของอ็อบเจ็กต์ ในขณะที่ ServiceCreatedEntity ถูกสร้างอินสแตนซ์และส่งคืนโดย CustomServiceClient ซึ่งจะบ่งชี้ว่าบางทีผู้สร้างไม่ได้เป็นเจ้าของมัน   -  person Andrew Gaspar    schedule 01.07.2014


คำตอบ (3)


มันเป็นคำถามมากกว่าว่าอะไรสร้างอะไร... ผู้สร้างควร (โดยทั่วไป) จัดการกับการฉีกขาดในโลกที่มุ่งเน้นคำขอ

person T McKeown    schedule 30.06.2014

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

person Eric Scherrer    schedule 30.06.2014

ฉันสับสนว่าทำไม CustomServiceClient มีเมธอดที่ส่งคืน ServiceCreatedEntity แต่ ServiceCreatedEntity ยังรับ CustomServiceClient เป็นพารามิเตอร์ในตัวสร้าง

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

ดูคำถามนี้เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ IDisposable

person Caleb Jares    schedule 30.06.2014