2010-01-29 13 views
8

Na przykład, mam metodę baza publikowania zdarzeń:.NET: Czy tworzenie nowych EventArgs za każdym razem, gdy zdarzenie uruchamia dobrą praktykę?

protected virtual OnSomeEvent(EventArgs e) 
    { 
     var handler = SomeEvent; 
     if (handler != null) 
     { 
      handler(this, e); 
      // handler(this, new EventArgs());// EDIT: Yes it should be 
              // handler(this, e), 
              // ignore this one :D 
     } 
    } 

dla klasy pochodnej, która nadpisuje OnSomeEvent i wnosi dodatkową zdarzenie, kiedy to pożary:

protected override OnSomeEvent(EventArgs e) 
    { 
     base.OnSomeEvent(e); 

     if (ExtendedEvent != null) 
     { 
      OnExtendedEvent(e); 
     } 
    } 

    protected void OnExtendedEvent(EventArgs e) 
    { 
     // some stuff done 
     // new information the ExtendedEventArgs object needs 
     // is not available until this point 

     ExtendedEvent(this, new ExtendedEventArgs(someStuff, someOtherStuff)); 
    } 

A jeśli wyprowadzenie idzie na tak , utworzy nowe wyprowadzone EventArgs dla każdej generacji klasy pochodnej, która tego wymaga. Jednak wydaje się, że różne wyprowadzenia z EventArgs na platformie .NET nie są zaprojektowane jako zmienne (bez ustawiania), to zniechęca obiekt do utrzymywania pojedynczej instancji EventArgs i modyfikowania jej w trakcie.

Za każdym razem, gdy zostanie wywołane takie zdarzenie, ponownie przydzielą pamięć dla wszystkich zaangażowanych obiektów EventArgs. W graficznej, intensywnej aplikacji, w której zdarzenie może być uruchamiane dziesiątki razy na sekundę (na przykład zdarzenie OnPaint na kontrolce), czy to naprawdę dobra praktyka?

Czy należy wprowadzić pewne zmiany w OnExtendedEvent() i zmienić wartość ExtendedEventArgs, aby uzyskać następujące możliwości?

protected ExtendedEventArgs extendedArgs = ExtendedEventArgs.Empty; 
    protected void OnExtendedEvent(EventArgs e) 
    { 
     // some stuff done 
     // new information the ExtendedEventArgs object needs 
     // is not available until this point 

     extendedArgs.someProperty1 = someStuff; 
     extendedArgs.someProperty2 = someOtherStuff; 

     ExtendedEvent(this, extendedArgs); 
    } 

EDYCJA: Naprawiono przykładowy kod, teraz powinien być wyraźniejszy.

+1

Wyprowadzanie nie jest problemem, klasa pochodna może wywoływać tylko base.OnExtendedEvent z EventArgs.Empty. Ogólnie rzecz biorąc, nie bój się tworzyć krótkotrwałych śmieci. –

+0

Myślę, że masz na myśli niezmienny zamiast zmiennego. Niezmienny oznacza, że ​​nie możesz go zmienić. – aaronb

Odpowiedz

3

Utworzę nowy niezmienny obiekt za każdym razem, gdy zostanie uruchomiony, ponieważ w argumencie zdarzenia znajdują się wartości.

Głównym powodem jest to, co by się stało, gdyby nowe wydarzenie zostało odpalone ponownie podczas obchodzenia istniejącego wydarzenia?

Będzie to zdarzyć w aplikacjach wielowątkowych, ale może nawet zdarzyć się na jednym wątku, jak pokazano w poniższym przykładzie:

pierwsze zdarzenie jest zwolniony z następujących wartości:

extendedArgs.someProperty1 = "Fire 1"; 
extendedArgs.someProperty2 = "Fire 1 Other Stuff"; 

Potem jakoś pierwsza procedura obsługi zdarzenia powoduje, że zdarzenie zostanie ponownie uruchomione z następującymi argumentami:

extendedArgs.someProperty1 = "Fire 2"; 
extendedArgs.someProperty2 = "Fire 2 Other Stuff"; 

Wszystkie programy do obsługi zdarzeń są dostępne e dla drugiego zdarzenia są przetwarzane, a teraz wracamy do przetwarzania pozostałych procedur obsługi zdarzeń dla pierwszego zdarzenia.

Teraz, od czasu użycia tego samego obiektu, wszystkie programy obsługi zdarzeń dla pierwszego zdarzenia będą miały teraz wartość "Fire 2" jako ich właściwość someProperty1, ponieważ drugie zdarzenie nadpisało wartości.

Wspomniany @nobugz nie bój się tworzyć krótkotrwałych śmieci.

1

Jestem trochę zdezorientowany twoim kodem OnExtendedEvent - czy chcesz wydedukować wydarzenie jako SomeEvent?

Gdy klient dodaje obsługi zdarzeń, oczekują oni są w stanie usunąć obsługi zdarzeń podczas obsługi zdarzenia, jak to:

someObject.SomeEvent += OnSomeEvent; 
// ... 
private void OnSomeEvent(object sender, EventArgs e) 
{ 
    someObject.SomeEvent -= OnSomeEvent; 
} 

Jeśli nie stosują standardową praktyką wysyłającego ten kod bardzo dziwnie rzuca wyjątek na osobę, która używa twojego kodu.

+0

Witam, przykro mi, że kod jest mylący. Naprawiono teraz: D – Dan7

5

Po pierwsze, po co stosować argument EventArgs do metody wypalania, jeśli tak czy inaczej go ignorujesz? To są prawdziwe odpady, ale zużycie zasobów jest mniej problematyczne niż kłamstwo, które twoja metoda mówi swoim rozmówcom. Wystarczy przekazać argument na rajd metoda wypalania prawdopodobnie nie będą miały istotne informacje dostępne w celu utworzenia EventArgs object i tak:

protected virtual OnSomeEvent(EventArgs e) 
{ 
    var handler = SomeEvent; 
    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

Więc teraz, że mamy to proste, jeśli EventArgs object ma istotnych informacji do opowiedzenia Twoi subskrybenci, po prostu użyj EventArgs.Empty, po to tam jest. Możesz zastosować ten sam wzorzec dla niestandardowych klas EventArgs, ale szczerze, martwisz się o nic. Tworzenie obiektów EventArgs nigdy nie będzie wąskim gardłem w twojej aplikacji, a jeśli tak, masz problemy z projektowaniem.

Powiązane problemy