Вопрос:

AddSingleton - время жизни - нужно ли классу реализовывать IDisposable?

c# asp.net-core dependency-injection garbage-collection

18 просмотра

2 ответа

30 Репутация автора

При использовании DI для служб, добавленных с использованием AddScopedили AddSingleton, необходимо ли внедрять службу IDisposable(даже если она не использует какие-либо неуправляемые ресурсы, такие как файлы)?

Ниже приведен пример из Документов Microsoft:

// Services that implement IDisposable:
public class Service1 : IDisposable {}
public class Service2 : IDisposable {}
public class Service3 : IDisposable {}

public interface ISomeService {}
public class SomeServiceImplementation : ISomeService, IDisposable {}

public void ConfigureServices(IServiceCollection services)
{
    // The container creates the following instances and disposes them automatically:
       services.AddScoped<Service1>();
       services.AddSingleton<Service2>();
       services.AddSingleton<ISomeService>(sp => new SomeServiceImplementation());

    // The container doesn't create the following instances, so it doesn't dispose of
    // the instances automatically:
       services.AddSingleton<Service3>(new Service3());
       services.AddSingleton(new Service3());
}

Что произойдет, если у меня есть этот код:

public class Service0  // (doesn't implement Disposable) 

services.AddScoped<Service0>();   // what happens to it when request scope ends? Does it stay on the heap?

services.AddSingleton<Service0>();   // it lives till application dies
services.AddSingleton(new Service0());  // ??
services.AddSingleton<IConfigureOptions<Service0>>((ctx) =>
   {
          return new ConfigureNamedOptions<Service0>(null, (config) =>
   {
// Do something here -- in debug mode it is executing this logic for each request
}}  // it is returning "new Service0" when a request is made. Does it mean for each request it returns new object and keeps in heap memory or returns same previously created object?
Автор: user2608601 Источник Размещён: 11.08.2019 06:42

Ответы (2)


0 плюса

129 Репутация автора

IDisposable - это просто интерфейс, который дает классу-исполнителю возможность выполнить некоторую очистку при уничтожении объекта, он ничего не делает сам по себе. DI уничтожит экземпляры, в зависимости от их времени жизни, таких как scoped, transient, Singleton, будет ли объект существовать после уничтожения в куче - это обязанность коллекционера Gorbagge. Если вы определяете новое instace внутри Singleton, то этот объект будет уничтожен с помощью Singleton instace и из-за времени жизни Singleton, которое истекает до конца времени жизни приложения, следовательно, оно будет следовать за временем жизни его родителя, за исключением случаев, когда вы выполняете там неуправляемые операции. ,

Автор: Ali Alp Размещён: 11.08.2019 08:36

0 плюса

5546 Репутация автора

нужно ли службе реализовывать IDisposable (даже если она не использует неуправляемые ресурсы, такие как файлы)

Обычно это не так, потому что основная цель IDisposable- освободить неуправляемые ресурсы. Однако есть еще одна причина для реализации IDisposable. Этот Dispose()метод иногда используется как ловушка для завершения действий, запускаемых в конструкторе. Например, конструктор запускает измерение длительности, в то время как Dispose()останавливает измерение и сообщает продолжительность некоторому механизму мониторинга.

Немного предыстории о IDisposable

Если объект не реализуется, IDisposableэто не значит, что он остается в куче. На самом деле, GC даже не знает, что это IDisposableтакое. Этот интерфейс является только шаблоном. Тем не менее, компилятор знает IDisposable, и он отправляет вызовы Dispose()в конце области usingоператора.

Кроме того, во многих случаях инфраструктурные слои или библиотеки (например, DI в ASP.NET Core) проверяют, реализует ли объект IDisposable, и если это так, вызывают Dispose()его.

Таким образом, тот факт, что объект реализует IDisposableсам по себе, не гарантирует, что Dispose()он будет вызван перед GC. Это зависит от пользователей объекта. Чтобы фактически обеспечить Dispose()до GC, полная реализация одноразового шаблона включает в себя вызов Dispose()«деструктора».

что происходит с ним, когда заканчивается область запроса? остается в куче? что происходит с ним, когда заканчивается область запроса?

  • AddScoped<Service0>(): в конце запроса ссылка на объект «забывается» (GC может удалить его в любой момент). Непосредственно перед тем, как забыть ссылку, объект проверяется на предмет того, реализует ли он IDisposable, и, если это так, Dispose()будет вызываться на нем.

  • AddSingleton<Service0>(): в конце срока службы веб-хоста ссылка на объект «забывается» (GC может удалить его в любой момент). Непосредственно перед тем, как забыть ссылку, объект проверяется на предмет того, реализует ли он IDisposable, и, если это так, Dispose()будет вызываться на нем.

  • AddSingleton(new Service0()): в конце срока службы веб-хоста ссылка на объект «забывается» (GC может удалить его в любой момент). Но так как этот объект был предоставлен извне и не был создан экземпляром DI, он не будет проверен IDisposableи Disposeне будет вызван.

Автор: felix-b Размещён: 11.08.2019 09:42
Вопросы из категории :
32x32