Не могу побороть, даже не побороть, а отловить когда происходит 2й вызов финализатора объекта. Все 3 объекта, должны быть уничтожены в определенном порядке, если это произойдет в произвольном порядке, то возможны либо утечки памяти, либо уничтожение статического неуправляемого объекта который отвечает за работоспособность 3х представленных объектов
Создание объектов:
Уничтожение:
В случае удаления функции финализаторов объектов, и использованием исключительно деструктора, все классы работают именно так как нужно.
Если возможно то подскажите где в данном коде вызываются финализаторы, за исключением выхода из Main
Код c# который управляет объектами:
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;
}
}
}
}
Финализаторы вызываются фоновым потоком финализации, в какой угодно момент и в произвольном порядке, только бы на объекты не было ссылок.
Ваш код не должен зависеть от порядка финализаторов, потому что он не гарантирован. Хуже того, вы не имеете права работать с управляемыми полями ваших объектов в финализаторе, т. к. они могут быть уже финализированы.
Если вам нужно контролировать удаление объектов, вам стоит воспользоваться интерфейсом IDisposable
. Вам придётся менять дизайн. Сорри.
Проблема решается очень просто, если после уничтожения неуправляемого объекта в деструкторе вызвать:
GC::SuppressFinalize(this);
То, повторный вызов не будет произведен.
Кто работал с RdotNet покажите пример, как получить матрицу различимости через QuickReduct в свой массив (C#)
Здравствуйте! Мне нужно сделать, чтоб пользователь вводил в TextBox'ы данные, они сохранялись в списке и добавлялись на DataGridViewДобавление в список...