2015-11-19 7 views
4

все. Я никогда не работал с деструкторами и не распоряжался, так что это ново для меня. У меня есть задача делать класс, который имеет деструктор и отчуждать методы, и что имеет UInt64 Id свойства, которое автоинкрементное и статический Dictionary<UInt64,MyClass>, который должен ссылаться на Id всех живые экземплярам MyClass.Как удалить управляемые и неуправляемые объекты в C#?

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

public class MyClass : IDisposable 
{ 
    private static Object Lock = new Object(); 
    private static Dictionary<UInt64, MyClass> LiveInstances = new Dictionary<UInt64, MyClass>(); 

    public UInt64 Id { get; private set; } 

    public MyClass() 
    { 
     lock (Lock) 
     { 
      var newId = IncrementalId(); 
      if (newId == 0) 
      { 
       throw new ArgumentException("Reached MAX VAL"); 
      } 
      Id = newId; 
      LiveInstances.Add(Id, this); 
     } 
    } 

    ~MyClass() 
    { 
     CleanUpNativeResources(); 
    }  

    public void Dispose() 
    { 
     lock (Lock) 
     { 
      CleanUpManagedResources(); 
      CleanUpNativeResources(); 
      GC.SuppressFinalize(this); 
     } 
    } 

    protected virtual void CleanUpManagedResources() 
    { 
     LiveInstances.Remove(Id); 

    } 
    protected virtual void CleanUpNativeResources() 
    { 

    } 

    private static UInt64 IncrementalId() 
    { 
     for (ulong i = 0; i <= Convert.ToUInt64(LiveInstances.Count) ; i++) 
     { 
      if (i != UInt64.MaxValue && !LiveInstances.ContainsKey(i + 1)) 
      { 
       return i+1; 
      } 
     } 
     return 0; 
    } 
} 

Теперь мой вопрос Как утилизировать объекты? ли я пытаюсь найти примеры располагающих объектов, я нахожу что-то вроде этого:

// Code to dispose the managed resources of the class 
Console.WriteLine("Object disposed"); 

Спасибо заранее.

+0

У вас нет неуправляемых ресурсов, ни неуправляемых ресурсов, которые реализуют 'IDisposable', так что вам не нужно реализовать' IDisposable'. Сборщик мусора позаботится обо всем для вас. –

+0

Хорошо. Но что, если я хочу избавиться от текущего экземпляра объекта? Мне нужно создать другие объекты и заменить удаленные объекты (это означает, что они будут использовать идентификаторы, которые удалили объекты, которые были использованы), и я не хочу, чтобы объекты с тем же идентификатором вокруг моей программы. –

ответ

3

Управляемые ресурсы будут автоматически утилизироваться сборщиком мусора в определенный момент времени. Неуправляемые ресурсы - это такие вещи, как Filehandles, полученные путем вызова Windows API, который возвращает дескриптор Windows, который необходимо освободить вручную. У вас нет ничего, что требует ручного удаления. Если вы не освободите эти дескрипторы, они останутся выделенными на время работы программы, но все .Net-классы, у которых есть неуправляемый ресурс, предоставляют Finalizer (см. Ниже), чтобы убедиться, что они, как правило, будут освобождены в какой-то момент ,

(Но если вы пишете свой собственный класс обработки файлов и забыли освободить дескриптор файла в любом месте на всех, файл будет оставаться открытым, пока ваша программа не вышла.)

Обычно такие неуправляемые ресурсы будут освобождены в два местонахождение:

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

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

Базовый шаблон Dispose используется идет что-то вроде этого:

class MyObject : IDisposable 
{ 
    //indicates if dispose has already been called 
    //private bool _disposed = false; 

    //Finalize method for the object, will call Dispose for us 
    //to clean up the resources if the user has not called it 
    ~MyObject() 
    { 
     //Indicate that the GC called Dispose, not the user 
     Dispose(false); 
    } 

    //This is the public method, it will HOPEFULLY but 
    //not always be called by users of the class 
    public void Dispose() 
    { 
     //indicate this was NOT called by the Garbage collector 
     Dispose(true); 

     //Now we have disposed of all our resources, the GC does not 
     //need to do anything, stop the finalizer being called 
     GC.SupressFinalize(this); 
    } 

    private void Dispose(bool disposing) 
    { 
     //Check to see if we have already disposed the object 
     //this is necessary because we should be able to call 
     //Dispose multiple times without throwing an error 
     if (!disposed) 
     { 
      if (disposing) 
      { 
       //clean up managed resources 
       components.Dispose(); 
      } 

      //clear up any unmanaged resources - this is safe to 
      //put outside the disposing check because if the user 
      //called dispose we want to also clean up unmanaged 
      //resources, if the GC called Dispose then we only 
      //want to clean up managed resources 
     } 
    } 
} 
+0

Хорошо, это помогло мне понять немного больше о предмете. Но у меня есть сомнения: мне нужно удалить экземпляр объекта в середине программы, чтобы создать новый экземпляр, а затем новый экземпляр заменит его место (я имею в виду, что не может быть двух экземпляров, которые имеют один и тот же идентификатор). Я знаю, что могу заставить вызвать коллекционер _Garbage Collector_, но я также знаю, что это не рекомендуемая практика **. Итак, как мне удалить этот экземпляр? Просто установив нулевое значение? –