Распределение всех членов в цикле - PullRequest
0 голосов
/ 10 мая 2018

У меня очень большой проект с несколькими страницами, где на каждой странице много IDisposable участников.

Я пытаюсь найти способ расположить все члены IDisposable в цикле, чтобы мне не приходилось вводить x1.Dispose(); x2.Dispose; ... xn.Dispose в каждом классе.

Есть ли способ сделать это?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Создайте метод, который будет распоряжаться всеми вашими одноразовыми объектами:

public void DisposeAll()
{
    x1.Dispose();
    x2.Dispose();
    x3.Dispose();
    . . .
}

и вызывать его там, где вам нужно.

0 голосов
/ 10 мая 2018

Использование отражения (не проверено):

    public static void DisposeAllMembersWithReflection(object target)
    {
        if (target == null) return;
        // get all fields,  you can change it to GetProperties() or GetMembers()
        var fields = target.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
        // get all fields that implement IDisposable
        var disposables = fields.Where(x => x.FieldType.GetInterfaces().Contains(typeof(IDisposable)));

        foreach (var disposableField in disposables)
        {
            var value = (IDisposable)disposableField.GetValue(target);
            if (value != null)
                value.Dispose();
        }
    }
0 голосов
/ 10 мая 2018

Конечно, просто убедитесь, что вы создали список для их хранения, и попробуйте, наконец, заблокировать себя, чтобы защитить себя от утечки.

// List for holding your disposable types
var connectionList = new List<IDisposable>();    

try
{ 
    // Instantiate your page states, this may be need to be done at a high level

    // These additions are over simplified, as there will be nested calls
    // building this list, in other words these will more than likely take place in methods
    connectionList.Add(x1);
    connectionList.Add(x2);
    connectionList.Add(x3);
}
finally
{
    foreach(IDisposable disposable in connectionList)
    {
        try
        {
            disposable.Dispose();
        }
        catch(Exception Ex)
        {
            // Log any error? This must be caught in order to prevent
            // leaking the disposable resources in the rest of the list
        }
    }
}

Однако такой подход не всегда идеален. Природа вложенных вызовов усложняется и требует, чтобы вызов был настолько высоко в архитектуре вашей программы, что вы можете рассмотреть возможность локальной обработки этих ресурсов.

Кроме того, этот подход критически не срабатывает в сценарии, где эти Одноразовые ресурсы интенсивны и должны быть немедленно освобождены. Хотя вы можете сделать это, то есть отследить ваши одноразовые элементы, а затем сделать все сразу, лучше всего попытаться получить время жизни объекта как short , насколько это возможно для управляемых ресурсов, подобных этому.

Что бы вы ни делали, не допускайте утечки одноразового ресурса. Если это потоки соединения и они неактивны в течение некоторого периода времени, также может быть целесообразно просто посмотреть на их состояние, а затем повторно использовать их в разных местах, вместо того, чтобы позволять им зависать.

...