Должны ли объекты, созданные 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. создаются явно с помощью оператора new (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