Zdarzenie po odpięciu nadal się wykonuje

0

Cześć, walczę z tym problemem od kilku dni, ale rozwiązanie jest pewnie nie tam gdzie szukam.

Mam aplikację WinForms, używam w niej zwenętrznej biblioteki, która między innymi monitoruje poziom sygnału odbieranego przez mikrofon i mogę zasubskrybować tą zmianę przez wystawiony event.

W mojej klasie 'nakładce' mam obiekt reprezentujący mikrofon z nieszczęsnym eventem Microphone.LevelChanged.

Podpinam tam przy inicjaizacji mojej klasy metodę:

private void Microphone_LevelChanged(object sender, XEventArgs<float> e)
        {
            MicrophoneLevel = e.Item;

            OnMicrophoneLevelChanged(e.Item);
        }

Z kolei OnMicrophoneLevelChanged() wygląda tak:

        private void OnMicrophoneLevelChanged(float value)
        {
            var handler = MicrophoneLevelChanged;
            if (handler != null)
                handler(this, new GEventArgs<float>(value));
        }

Jak widać moja klasa wystawia event MicrophoneLevelChanged, do którego już w programie podpinam metodę, która ustawia progress bar na poziom zgodny z natężeniem dźwięku odbieranym przez mikrofon. Value progressbara musze ustawiać w formatce przez Invoke(), więc jak rozumiem poziom sygnału jest monitorowany gdzieś w osobnym wątku.

Klasa Microphone z zewnetrznej, nie mojej biblioteki już sama mnie informuje o zmianie poziomu sygnału i ustawiam go tak:

        public void MediaHandlers_MicrophoneLevelChanged(object sender, GEventArgs<float> e)
        {
            if (MainForm.IsDisposed || MainForm.pbMic.IsDisposed) return;

            MainForm.Invoke(new Action(() =>
            {
                if (MainForm.IsDisposed || MainForm.pbMic.IsDisposed) return;
                MainForm.pbMic.Value = (int)e.Item;
            }));
        }

I tutaj problem

W zdarzeniu FormClosing formatki odpinam MediaHandlers_MicrophoneLevelChanged, a następnie formatka jak i program się zamyka.
Niestety w tym momencie debugger łapie mi wyjątek ObjectDisposedException przy próbie ustawienia MainForm.pbMic.Value.

Problem polega na tym, że MediaHandlers_MicrophoneLevelChanged przecież odpiąłem zaraz na początku FormClosing więc teoretycznie program nie powinien tam wcale wejść.
Uprzedzając: na pewno
MicrophoneLevelChanged += MediaHandlers_MicrophoneLevelChanged; zostaje wykonane tylko raz, ale dla pewności wykonuje nawet parę razy
MicrophoneLevelChanged -= MediaHandlers_MicrophoneLevelChanged; w FormClosing

Mimo tego program nadal tam wchodzi i się wywala na próbie ustawienia wartości na progressbarze.

Ręce mi opadły, macie jakieś pomysły czym to może być spowodowane i jak sobie z tym radzić?

0

Chyba się udało!
Nie wiem czy to możliwe, ale dla własnych potrzeb wyobrażam sobie, że mimo odpięcia zdarzeń w jakiejś kolejce siedzi jeszcze lista zdarzeń do wykonania i wykonuje się ona już przy niszczeniu formatki. Może ktoś to rozwinąć? Dobrze kombinuje?

Pomogła taka linijka po odpięciu metody od eventa, a przed zamknięciem okna:
Application.DoEvents()

Będę wdzięczny jeśli ktoś będzie w stanie napisać coś więcej na temat tego przypadku bo zrobiłem to na czuja.

0

Moim zdaniem powinieneś się w swojej klasie opakowującej bibliotekę pozbyć problemu wątka, używając tam Invoke.
W kodzie formy wtedy już się tym nie przejmujesz.

1 użytkowników online, w tym zalogowanych: 0, gości: 1