2015-01-22 4 views
3

Я ищу совет о том, как и когда реализовать шаблон размещения.
Я прочитал статью MSDN о том, как реализовать шаблон Dispose(). Это имеет смысл. Я реализовал его в своем классе, но, похоже, это не влияет на использование памяти.Как правильно реализовать Dispose() в моем классе?

Немного фона, я строю 2d сверху вниз игровой движок. У меня есть единицы, называемые Gatherer, которые наследуются от Actor (базовый класс для рисования спрайта и отслеживания viewplane), и они простые спрайты, которые выходят и делают что-то. Они исчезают после 5 игровых раундов игры.

Я использую список для отслеживания собирателей, реализованных как это:

List<Gatherer> gatherList = new List<Gatherer>(); 

Тогда я подрезать список, как это внутри игрового движка:

public void pruneDeadFollowers() 
{ 
for (int i = gatherList.Count-1; i> -1; i--)    
    { 
     if (gatherList[i].timeToDie) //Bool to check if unit needs to be removed this round. 
     {      
      this.dropActor(gatherList[i]); //Calls method that unsubscribes the object from triggered events. 
      gatherList[i].Dispose(); //Is this needed? 
      gatherList.RemoveAt(i); //Remove from list. 
     } 
    } 
} 

Объект сборщика довольно прост. Он имеет в основном управляемые объекты.
В нем много полей Int, пара List, пара Point (From Monogame), пара объектов Bool и несколько Static Int. У меня также есть Random r; созданный во время выполнения, но у него, похоже, нет метода Dispose. Единственные неуправляемые объекты, которые у меня есть, - это 2 объекта Texture2D. public Texture2D glowTexture; public Texture2D texImage;

В моем распоряжении, я думаю, мне нужно только избавиться от текстур.
Единственная проблема в том, что если я на самом деле называю texImage.Dispose(); он разрушает текстуру для остальных единиц, которые все еще живы. Я думаю, что могу просто сделать текстуру Null вместо этого, которая не влияет на существующие единицы.

У меня есть это распоряжение: достаточно ли этого? Если нет, как я могу проверить, что он работает по мере необходимости?

public void Dispose() 
{ 
    Dispose(true); 
    GC.SuppressFinalize(this); 
} 

// Protected implementation of Dispose pattern. 
protected virtual void Dispose(bool disposing) 
{ 
    if (disposed) 
     return; 

    if (disposing) 
    {       
     glowTexture = null; 
     texImage = null; 
    } 

    disposed = true; 
} 
+0

Обратите внимание, что вам не нужен 'GC.SuppressFinalize (this);' если у вас на самом деле нет финализатора в вашем объекте. Это происходит только тогда, когда вы реализуете '~ MyObject() {Dispose (false); } '. Если вы его реализуете (вот целая точка шаблона, за которым вы следуете), часть 'if (disposing) {}' должна выполняться только на ** управляемых ** ресурсах, а не на неуправляемых (они должны быть освобождены финализатор, если вы забыли вызвать 'Dispose()'). Неуправляемые ресурсы всегда должны свободно игнорировать параметр. – Jcl

+0

Параметр 'disposing' должен действительно называться' amIBeingCalledDeterministically' :-) – Jcl

ответ

4

Ваша реализация действительна, но на самом деле не достаточна.

Dispose Используется для выпуска неуправляемых ресурсов, как вы уже нашли. Ваша первоначальная реализация (где вы разместили текстуры после их использования) была правильной.

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

Я буду следовать шаблону в XNA. Тот, кто загружает контент, также должен его выгружать. В вашем случае, кто-то создает, текстуры (и, следовательно, дочерние объекты) должны располагать их, когда они расположены. Для дочерних объектов, использующих текстуры, на самом деле не нужно реализовывать IDisposable от всего, что я вижу.

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