2013-05-31 4 views
3

Чтобы изучить встроенный интерфейс C#, я работал над оболочкой OpenGL. Сам API OpenGL - это конечный автомат, привязанный к определенному потоку. Когда объект, содержащий собственные ресурсы, собирает мусор, финализатор работает в потоке GC и не может напрямую освобождать ресурсы.Сбор мусора в C#; удаление объектов в конкретном потоке

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

Проблема заключается в том, что если GC собирает, когда он выполняет итерацию через этот список, foreach терпит неудачу, поскольку коллекция была изменена. Я не могу просто помещать мьютекс в список, так как GC является stop-the-world в большинстве реализаций, и если цикл рисования заблокировал его, он никогда не завершит итерацию и не разблокирует ее снова.

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

Какой может быть лучший подход здесь?

+0

Вы используете шаблон размещения в контейнере, чтобы освободить ресурсы в потоке до окончания потока? –

+0

Вы пытались [отключить параллельный GC] (http://msdn.microsoft.com/en-us/library/at1stbec.aspx)? Не совсем уверен, относится ли это, но может стоить проверить. –

+1

Я не могу не думать, что лучшим вариантом здесь будет использование 'use' /' Dispose() ', а не финализатор, чтобы освободить эти ресурсы. –

ответ

1

Тогда вы собираетесь стиснуть зубы и прекратить полагаться на GC, чтобы сделать ваше управление ресурсами для вас. Вам нужно будет, чтобы ваш менеджер активов имел явную функцию для удаления объектов, которые он выделяет, вместо того, чтобы полагаться на функцию финализатора менеджера активов. И вам придется называть эту функцию в определенном месте вашего кода.

Просто потому, что у вас есть GC не означает, что это лучшее или единственное решение.

+1

Это смешно, все выглядит как гвоздь! – jameswilddev

0

Вы всегда можете использовать инструкцию fixed.

Смотрите здесь http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

+0

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

+0

Действительно, но спасибо за ваш вклад. – jameswilddev

+0

Вопрос заключается в предотвращении сбора GC в определенной области исполнения. Это именно то, для чего предназначен фиксированный оператор. Вы правы, хотя для фиксированного оператора требуется использование неуправляемого кода, но, по сути, прекращение сбора GC. – jaywayco

1

Спрашивающие написал/заявил:

сам OpenGL API является конечным автоматом, который привязан к конкретной теме.

Это Не верно!

Контексты OpenGL могут быть активны только в одном потоке за раз. Это не означает, что контексты не могут использоваться из разных потоков. По сути, контекст OpenGL представляет собой взаимоисключающий ресурс (hint: Mutex), который должен быть связан перед его использованием ({wgl,glX}MakeCurrent(DC, RC)) в потоке и после выполнения с учетом того, что требуется для контекста, вы отключаете из текущего потока контекст OpenGL ({wgl,glX}MakeCurrent(NULL, NULL)).

+0

Я не могу просто взять контроль над контекстом из потока GC (который, возможно, остановил мир), в совершенно случайное время, хотя верно? В настоящее время с помощью GLFW открывается окно, поэтому у меня нет доступа к аргументам, которые мне нужно будет предоставить, хотя это, скорее всего, в конечном итоге. Спасибо за разъяснение. – jameswilddev

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^