Почему я не должен использовать GC.Collect () - PullRequest
0 голосов
/ 20 апреля 2011

Я занимаюсь разработкой приложения, в котором я работаю с CertAdm.dll для подключения к центру сертификации.Иногда я получаю сообщение об ошибке "Была предпринята попытка открыть сеанс базы данных центра сертификации, но активных сеансов уже слишком много. Возможно, необходимо настроить сервер для разрешения дополнительных сеансов."

Если я настраиваю свое соединение, как показано ниже, я не получаю сообщение об ошибке, и все работает нормально.

CERTADMINLib.ICertView2 cv2 = new CERTADMINLib.CCertViewClass();

try
{
    cv2.OpenConnection(srtCAConfig);
}
catch
{
    GC.Collect();
    GC.WaitForPendingFinalizers();
    cv2.OpenConnection(srtCAConfig);
}

Теперь меня интересует, что я много читал там, где люди говорят, что не следуетt использовать GC.Collect ().Почему я не должен?Это решает мою проблему?

Вся помощь очень ценится.

Ответы [ 3 ]

4 голосов
/ 20 апреля 2011

Краткий ответ: сбор мусора становится менее эффективным, чем больше вы его делаете.

Ожидание ожидающих финализаторов также нежелательно.Вы задерживаете свой код для ожидания неизвестного числа объектов для выполнения операций очистки, которые могут занять неизвестное количество времени.Если вы исправите основную проблему, вам не нужно будет ждать ни одной из них.

Что касается основной проблемы, когда объекту принадлежит какой-то внешний (дефицитный) ресурс, важно, чтобы, когда выпокончив с этим, вы вызываете соответствующий метод для освобождения ресурса.Часто это метод с именем Dispose (), CloseConnection () или что-то подобное.

однако, это объект взаимодействия COM, и все MSDN говорит:

Чтобы закрыть соединение, вызовитефункцию Release (C ++) или установите для объекта значение Nothing (Visual Basic).

В .NET эквивалентно вызывать System.Runtime.InteropServices.Marshal.ReleaseComObject (cv2).Как только вы это сделаете, объект, на который ссылается cv2, недействителен, поэтому не вызывайте его снова.

0 голосов
/ 20 апреля 2011

Я думаю, что вы не закрываете соединения после их открытия, и, наконец, оно превышает максимальное количество соединений, которые могут быть открыты одновременно.Когда вы передаете GC.Collect (), каждый раз, когда объект соединения принудительно собирается, из-за чего вы не можете повторно использовать уже открытое соединение.

0 голосов
/ 20 апреля 2011

Возможно, это решит вашу проблему из-за некорректной работы с соединениями в вашем классе.

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

...