Это упрощенная версия кода, которая у меня есть, которая не очищается в ожидаемом порядке.Этот пример кода вызывает нарушение доступа при выходе, поскольку переносимый собственный объект удаляется, прежде чем он может быть отписан от подписки.
Сценарий состоит в том, что клиент C # создает два конкретных объекта CLI и сохраняет их в качестве дескрипторов интерфейса.Затем один конкретный объект настраивается для хранения ссылки на другой, снова через дескриптор интерфейса.Это отношение установлено для предоставления управляемых оболочек для двух классов, где один подписывается на другой на собственном уровне.
Я ожидаю, что, например, объект A, содержащий ссылку на объект B, предотвратит завершение объекта B /расположен?Это не то, что я наблюдаю.Есть ли лучший способ представить отношения так, чтобы очистка была правильной?
Собственные классы:
#pragma managed(push, off)
class CNative2;
//------------------------------------------------------------------------------
class CNative1
{
public:
CNative1(){}
~CNative1(){}
void Subscribe( CNative2* pn2 )
{
m_pn2 = pn2;
}
void Unsubscribe()
{
m_pn2 = 0;
}
CNative2* m_pn2;
};
//------------------------------------------------------------------------------
class CNative2
{
public:
CNative2(){}
~CNative2()
{
m_pn1->Unsubscribe();
}
void Initialize( CNative1* pn1 )
{
m_pn1 = pn1;
m_pn1->Subscribe( this );
}
private:
CNative1* m_pn1;
};
#pragma managed(pop)
Код библиотеки классов CLI:
#include "Native.h"
using namespace System;
namespace CLILib
{
//------------------------------------------------------------------------------
public interface class Interface1
{
};
//------------------------------------------------------------------------------
public interface class Interface2
{
void Initialize( Interface1^ i1 );
};
//------------------------------------------------------------------------------
public ref class Class1 : Interface1
{
public:
Class1()
{
m_pn1 = new CNative1();
};
~Class1()
{
this->!Class1();
}
!Class1()
{
delete m_pn1;
}
internal:
CNative1* GetNative()
{
return m_pn1;
}
private:
CNative1* m_pn1;
};
//------------------------------------------------------------------------------
public ref class Class2 : Interface2
{
public:
Class2()
{
m_pn2 = new CNative2();
}
~Class2()
{
this->!Class2();
}
!Class2()
{
delete m_pn2;
}
virtual void Initialize( Interface1^ i1 )
{
m_i1 = i1;
Class1^ c1 = safe_cast< Class1^ >( i1 );
m_pn2->Initialize( c1->GetNative() );
}
Interface1^ m_i1;
private:
CNative2* m_pn2;
};
}
C #Код клиента:
using CLILib;
namespace ManagedClient
{
class Program
{
static void Main( string[] args )
{
for ( int i = 0; i < 1000000; ++i )
{
Interface1 i1 = new Class1();
Interface2 i2 = new Class2();
i2.Initialize( i1 );
}
}
}
}