Podpinanie się pod event - czy trzeba na niego czekać w pętli?

0
 public class Udostepniajaca
    {
        public delegate void MojDelegat();
        public event MojDelegat MojEvent;

        public bool running = false;

        public void Start()
        {
            running = true;
            new Thread(new ThreadStart(ZrobCos)).Start();
        }

        public void Stop() { running = false; }

        public void ZrobCos()
        {
            while (running)
            {
                System.Threading.Thread.Sleep(300);
                MojEvent();
            }
        }

    }

    public class Wykorzystujaca
    {
        
        public void Start()
        {
            Udostepniajaca obiekt = new Udostepniajaca();
            obiekt.MojEvent += new Udostepniajaca.MojDelegat(obiekt_MojEvent);
            obiekt.Start();
        }

        void obiekt_MojEvent()
        {
            Console.WriteLine("Event, teraz: " + DateTime.Now.ToLongTimeString());
        }

    }
    public class Program
    {
        static void Main(string[] args)
        {
            Wykorzystujaca wykorzystujaca = new Wykorzystujaca();
            wykorzystujaca.Start();
            wykorzystujaca = null;
            GC.Collect();
            Console.ReadLine();
        }
    }
 

Działa bez przerwy. Dlaczego? Tzn jak długo jeszcze "podziała"? Ogólnie chciałbym się dowiedzieć, czy nie potrzebuję żadnej pętli czekającej (w klasie Wykorzystujaca) na eventy wywoływane z innej klasy (Udostepniajacej), bo nie wiem czy mi w końcu GarbageCollector nie usunie "czekającego", co troche rozkraczy aplikację.

Pozdrawiam i dzięki z góry za odpowiedź.

0

Działa bez przerwy, dokładniej zdarzenie odpala się co 300 milisec. Bo tak napisałeś.
W wątku odpalonym w Udostepniajaca co 300 ms rzucasz event, który łapany jest przez Wykorzystujaca.
Nie rozumiem po co ci pętla, o której piszesz? Nie wiesz ile eventów przyjdzie, ale jak przyjdzie chcesz go obsłużyć.
Rozumiem że ten post wiąże się z twoim poprzednim, więc lepszym rozwiązaniem byłoby aby Udostepniajaca na rozpoczęcie pracy rzucałaby jeszcze event mówiący o rozpoczęciu pracy oraz na zakończenie o zakończeniu pracy.
Poza tym bardzo optymistycznie rzucasz event. Oczywiście nie dostałeś wyjątku, bo jest podpięta obsługa zdarzenia pod niego, ale nie musi być, dlatego generalnie eventy wywołuje się sprawdzając uprzednio czy nie są one null.

if (MojEvent != null) MojEvent();

wykorzystujaca = null; ustawiasz tą zmienną na nul nie wiedząc czy Udostepniajaca skończyła już pracę. Event informujący o końcu pracy powinien być pomocny.

0

Kiedy podpinasz eventa obydwie klasy zarówno wykorzystująca jak i udostępniająca dostają swoje referencje, więc przypisanie null do wykorzystującej nie spowoduje usunięcia przez GC ponieważ udostępniająca nadal ma do niej referencję. Obiekt zostanie usunięty przez GC kiedy do obiektu nie będzie żadnej referencji, czyli kiedy odepniesz EventHandlera.

I nie potrzebujesz tego Console.ReadLine() na końcu, żeby zatrzymać kod. Masz odpalony wątek więc ten program zakończy się dopiero z jego zakończeniem, bo to jest wątek typu foreground.

Pozdrawiam
Łukasz Gawron

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