Объекты этой структуры будут в неуправляемой памяти, То есть зафиксированы.
Неуправляемые объекты не подвергаются процессу сбора мусора - они вообще не проверяются.
Вот и происходит следующее:
1. Имеется массив объектов неуправляемой памяти
2. В каждом объекте имеется ссылка на объект управляемой памяти
3. GC запускается и т.к. неуправляемые объекты не проверяются, то объекты на которые ссылаются неправляемые исчезают, т.к. ссылок на них, возможно, больше не осталось.
Попробуй:
- Вызвать GC.KeepAlive на ссылках управляемой памяти (кол-беках)
var funces = new Fun[];
// Код
GC.KeepAlive(funces);
- Либо сохраняй массив объектов управляемой памяти вместе с целевым массивом, чтобы переменная с этим массивом хранилась в этом же методе и на нем вызови
GC.KeepAlive
(иначе область видимости ограничивается методом, в котором они создались). Примерно так:
var (arr, managedObjects) = Create(funces);
// Код
GC.KeepAlive(managedObjects);
- Либо, попробуй перед началом работы метода запрещать сборку мусора -
GC.TryStartNoGCRegion
/
GC.EndNoGCRegion
Самое что непонятное. хоть вопрос на что где когда отправляй, почему то ломается то нет.
Во-первых, работа GC не детерминирована - он может запуститься в любой момент.
Во-вторых, DEBUG или RELEASE режимы компиляции добавляют различные оптимизации и т.д. в процесс работы.
В-третьих, при подключенном дебагере все локальные переменные не будут собраны GC, т.к. на них неявно появляются указатели.