Судя по всему, что я прочитал, должен быть один поток GC для вызова всех финализаторов. Теперь вопрос в том, какова сфера действия этого «одного» потока - для каждого процесса или для каждого домена приложения, поскольку вся цель доменов состоит в том, чтобы разделить и сделать «независимые» разные приложения в одном пространстве процессов.
Я прочитал здесь:
Если в финализаторе возникает необработанное исключение, исполняемый поток CLR принимает исключение, обрабатывает финализатор, как если бы он завершился нормально, удаляет его из очереди freachable и переходит к следующей записи.
Однако более серьезным является то, что происходит, если ваш финализатор не завершает работу по какой-либо причине, например, он блокируется, ожидая условия, которое никогда не возникает. В этом случае поток финализатора будет зависать, поэтому финализируемые объекты больше не будут собираться мусором. Вы должны хорошо знать об этой ситуации и придерживаться простейшего кода для освобождения неуправляемых ресурсов в финализаторах. .
Еще одно соображение - это то, что происходит при завершении работы приложения. Когда программа закрывается, сборщик мусора будет пытаться вызвать финализаторы всех финализируемых объектов, но с некоторыми ограничениями:
Завершаемые объекты не переводятся в более высокие поколения кучи во время завершения работы.
Каждому индивидуальному финализатору дается максимум 2 секунды на выполнение; если это займет больше времени, он будет убит.
Максимальное время выполнения всех финализаторов составляет 40 секунд; если какие-либо финализаторы все еще выполняются или ожидают на этом этапе, весь процесс внезапно завершается.
Слишком много сообщений (и даже официальная документация) злоупотребляют терминами «приложение», «процесс» и «домен приложения» - большинство из них даже предполагает, что они равны, потому что обычно приложения запускаются в одном домене приложения в одном процессе. . Такое неправильное использование делает все эти документы трудными для чтения и даже бесполезными.
Итак, мой вопрос предполагает наличие нескольких приложений, каждое из которых выполняется в отдельном домене приложения в одном процессе.
Все ли эти приложения используют одни и те же потоки сборки мусора и финализатора? Повлияет ли проблема, описанная в статье выше (тема зависания финализатора), на все приложения в этом процессе? Если да - есть ли обходной путь (кроме того, чтобы не использовать плохие приложения), например, как-то обнаружить поток финализатора и отправить его Thread.Abort?
Все вышесказанное связано с тем, что я столкнулся с аналогичной проблемой. Мое приложение работает в отдельном домене приложений как надстройка к стороннему программному обеспечению (Outlook). По разным причинам мне нужно вызвать GC.Collect и GC.WaitForPendingFinalizers, чтобы полностью освободить COM-ссылки (обычных процедур взаимодействия недостаточно для Office / Outlook), когда работает конкретная сторонняя надстройка, мой GC.WaitForPendingFinalizers зависает навсегда , поэтому я подозреваю, что в добавлении третьей стороны есть "плохой" финализатор. У меня нет контроля над заменой / удалением этого добавления (требования клиента), поэтому я должен сам выяснить, как заставить их сосуществовать.