Требуется ли «Утилизация» для переменной в цикле, созданном с помощью «Активатора».Создать установку»?

#c#

Вопрос:

Я создаю динамическую переменную (действие) с Activator.CreateInstance помощью цикла. Должен ли я использовать Dispose перед следующим циклом? Каков оптимальный код переменной действия для предотвращения утечек памяти?

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        var job = await DbHelper.FromProcAsync<JobQueue>("WJbQueue_Start1st", cancellationToken: stoppingToken);

        if (job?.JobId > 0)
        {
            dynamic action = Activator.CreateInstance(Type.GetType(job.ActionType));

            await action.ExecuteAsync(stoppingToken);

            // Do I need Dispose for action variable here?
        }

        await Task.Delay(1000, stoppingToken);
    }
}
 

Комментарии:

1. Почему ты думаешь, что тебе не следует звонить Dispose() ?

2. просто по коду мы видим много выделений памяти, но освобождение не очевидно …

3. (action as IDisposable)?.Dispose();

Ответ №1:

Если рассматриваемый класс реализует IDisposable , то да, было бы хорошей практикой позвонить .Dispose() до того, как ваша последняя ссылка на него выйдет за рамки.

В этом весь смысл этого интерфейса.

Однако вам предстоит выяснить, действительно ли класс реализует интерфейс. Поскольку это динамично, мы не можем сказать наверняка. И вы тоже не можете во время компиляции.

Ответ №2:

все объекты не могут быть удалены, и при добавлении action.Dispose() вы можете столкнуться с проблемами во время работы
, поэтому сделайте это

 protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        var job = await DbHelper.FromProcAsync<JobQueue>("WJbQueue_Start1st", cancellationToken: stoppingToken);

        if (job?.JobId > 0)
        {
            dynamic action = Activator.CreateInstance(Type.GetType(job.ActionType));

            await action.ExecuteAsync(stoppingToken);

            // check object is disposable 
            if ( action is IDisposable )
                action.Dispose();
        }

        await Task.Delay(1000, stoppingToken);
    }
}