I can not overcome, not even overcome, and catch when the 2nd call of the object's finalizer occurs. All 3 objects must be destroyed in a certain order, if this happens in an arbitrary order, then either memory leaks or destruction of a static unmanaged object that is responsible for the performance of 3 presented objects

Creating objects:

  1. VlcInstance
  2. VlcMediaPlayer / VlcMedia
  3. VlcMedia / VlcMediaPlayer

Destruction:

  1. VlcMedia
  2. VlcMediaPlayer
  3. VlcInstance

In case of removal of the function of object finalizers, and using exclusively destructor, all classes work exactly as needed.

If possible, tell me where in this code finalizers are called, except for exiting from Main

The c # code that controls objects:

 using System; namespace libvlc.net.test.csharp { class Program { static VlcInstance vlcInstance; static VlcMediaPlayer vlcPlayer; static VlcMedia vlcMedia; static void Main(string[] args) { string path = System.IO.Path.Combine("..\\..\\libvlc-data\\2.2.6\\bin\\", IntPtr.Size == 4 ? "x86\\" : "x64"); vlcInstance = new VlcInstance(path, "-I", "logger,none", "-vv", "--no-plugins-cache", "--ignore-config"); vlcPlayer = new VlcMediaPlayer(vlcInstance); ConsoleKeyInfo cki; while(((cki = Console.ReadKey(true)).Key != ConsoleKey.Escape)) { switch (cki.Key) { case ConsoleKey.Spacebar: vlcPlayer.TooglePause(); break; case ConsoleKey.RightArrow: vlcPlayer.Stop(); if (!(vlcMedia is null)) { vlcMedia.MediaEvent -= VlcMedia_MediaEvent; vlcMedia.Dispose(); } vlcMedia = new VlcMedia(vlcInstance, new Uri(System.IO.Path.Combine("https://raw.githubusercontent.com/isyami/libvlc.net/master/", "test2"))); vlcMedia.MediaEvent += VlcMedia_MediaEvent; vlcPlayer.Open(vlcMedia); break; case ConsoleKey.LeftArrow: vlcPlayer.Stop(); if (!(vlcMedia is null)) { vlcMedia.MediaEvent -= VlcMedia_MediaEvent; vlcMedia.Dispose(); } vlcMedia = new VlcMedia(vlcInstance, new Uri(System.IO.Path.Combine("https://raw.githubusercontent.com/isyami/libvlc.net/master/", "test"))); vlcMedia.MediaEvent += VlcMedia_MediaEvent; vlcPlayer.Open(vlcMedia); break; } } vlcMedia = null; vlcPlayer = null; vlcInstance = null; GC.WaitForPendingFinalizers(); GC.Collect(); } private static void VlcMedia_MediaEvent(object s, VlcMediaEventArgs a) { switch (a.EventType) { case VlcMediaEvent.MetaChanged: Console.WriteLine($"{a.EventType}: \t\t{a.EventData.NewMeta}"); break; case VlcMediaEvent.SubItemAdded: Console.WriteLine($"{a.EventType}: NewSubItem"); break; case VlcMediaEvent.DurationChanged: Console.WriteLine($"{a.EventType}: \t{a.EventData.NewDuration}"); break; case VlcMediaEvent.ParsedChanged: Console.WriteLine($"{a.EventType}: \t\t{a.EventData.NewParsed}"); break; case VlcMediaEvent.Freed: Console.WriteLine($"{a.EventType}: \t\tMediaFreed"); break; case VlcMediaEvent.StateChanged: Console.WriteLine($"{a.EventType}: \t\t{a.EventData.NewState}"); break; default: break; } } } } 
  • 3
    What are the calls of GC.WaitForPendingFinalizers and GC.Collect at the end of the Main function, in exactly this order? Running garbage collection before exiting the program is pointless, and the CLR finalizers automatically launch at the end of the process - MSDN.WhiteKnight
  • Why demolished the answer? It is really necessary to call SuppressFinalize in Dispose (this is recommended both by the documentation and the final answer in the related question). I have no idea why he was zaminusovali. - MSDN.WhiteKnight
  • @ MSDN.WhiteKnight: Well, those who have not read the documentation and zaminusovali =) - LLENN

1 answer 1

Finalizers are called by the background stream of finalization, at any time and in any order, if only the objects are not referenced.

Your code should not depend on the order of the finalizers, because it is not guaranteed. Worse, you do not have the right to work with the managed fields of your objects in the finalizer, since they can already be finalized.

If you need to control the removal of objects, you should use the IDisposable interface. You will have to change the design. Sorry.

  • one
    You might be interested in this: ru.stackoverflow.com/q/486696/10105 - VladD
  • How do my hands begin to fall when it comes to such .NET that I can not free up the memory as necessary? - LLENN
  • @Yami: So you still look towards IDisposable . It is specifically for this and invented. - VladD