Czy istnieje sposób, aby stwierdzić, czy do obiektu dodano moduł obsługi zdarzeń? Serializuję listę obiektów do / poza stan sesji, abyśmy mogli użyć stanu sesji opartego na SQL ... Gdy obiekt na liście ma zmienioną właściwość, musi zostać oflagowany, o czym obsługiwała wcześniej obsługa zdarzeń . Jednak teraz, gdy obiekty są przekształcane w postaci szeregowej, nie jest obsługiwane moduł obsługi zdarzeń.
W przypływie lekkiego rozdrażnienia właśnie dodałem moduł obsługi zdarzeń do właściwości Get, która uzyskuje dostęp do obiektu. Jest teraz wywoływany, co jest świetne, z wyjątkiem tego, że jest wywoływany 5 razy, więc myślę, że program obsługi dodaje się za każdym razem, gdy uzyskiwany jest dostęp do obiektu.
Jest to naprawdę wystarczająco bezpieczne, aby po prostu zignorować, ale wolę uczynić to o wiele czystszym, sprawdzając, czy moduł obsługi został już dodany, więc robię to tylko raz.
Czy to jest możliwe?
EDYCJA: Niekoniecznie mam pełną kontrolę nad tym, jakie procedury obsługi zdarzeń są dodawane, więc samo sprawdzenie wartości null nie jest wystarczająco dobre.
Odpowiedzi:
Spoza definiującej klasy, jak wspomina @Telos, możesz używać EventHandler tylko po lewej stronie a
+=
lub a-=
. Tak więc, jeśli masz możliwość zmodyfikowania klasy definiującej, możesz podać metodę wykonania sprawdzenia, sprawdzając, czy jest to moduł obsługi zdarzeńnull
- jeśli tak, to nie został dodany moduł obsługi zdarzeń. Jeśli nie, to może i możesz przeglądać wartości w Delegate.GetInvocationList . Jeśli jeden jest równy delegatowi, który chcesz dodać jako moduł obsługi zdarzeń, to wiesz, że tam jest.Można to łatwo zmodyfikować, aby stało się „dodaj moduł obsługi, jeśli go nie ma”. Jeśli nie masz dostępu do wnętrz klasy, która wystawia wydarzenie, być może będziesz musiał zbadać
-=
i+=
, zgodnie z sugestią @Lou Franco.Lepiej jednak ponownie przeanalizuj sposób, w jaki zamawiasz i likwidujesz te obiekty, aby sprawdzić, czy nie możesz samodzielnie znaleźć sposobu na śledzenie tych informacji.
źródło
Delegate.Equals(objA, objB)
jeśli chcesz sprawdzić dokładnie taki sam poziom delegowania. W przeciwnym razie porównaj właściwości indywidualnie jakif(objA.Method.Name == objB.Method.Name && objA.Target.GetType().FullName == objB.Target.GetType().FullName)
.Niedawno doszedłem do podobnej sytuacji, w której musiałem zarejestrować program obsługi zdarzenia tylko raz. Odkryłem, że możesz najpierw bezpiecznie wyrejestrować się, a następnie zarejestrować ponownie, nawet jeśli program obsługi nie jest w ogóle zarejestrowany:
Pamiętaj, że robienie tego za każdym razem, gdy się rejestrujesz, zapewni, że twój przewodnik zostanie zarejestrowany tylko raz. Brzmi dla mnie całkiem niezła praktyka :)
źródło
Jeśli jest to jedyny moduł obsługi, możesz sprawdzić, czy zdarzenie ma wartość NULL, jeśli nie jest, moduł obsługi został dodany.
Myślę, że możesz bezpiecznie zadzwonić - = na zdarzenie ze swoim operatorem, nawet jeśli nie zostało dodane (jeśli nie, możesz je złapać) - aby upewnić się, że nie ma go przed dodaniem.
źródło
Ten przykład pokazuje, jak użyć metody GetInvocationList (), aby pobrać delegatów do wszystkich dodanych procedur obsługi. Jeśli chcesz sprawdzić, czy został dodany określony moduł obsługi (funkcja), możesz użyć tablicy.
Możesz sprawdzić różne właściwości we właściwości Method delegata, aby sprawdzić, czy konkretna funkcja została dodana.
Jeśli chcesz sprawdzić, czy jest tylko jeden dołączony, możesz po prostu przetestować na wartość null.
źródło
Jeśli dobrze rozumiem twój problem, możesz mieć większe problemy. Powiedziałeś, że inne obiekty mogą subskrybować te wydarzenia. Gdy obiekt jest szeregowany i zserializowany, inne obiekty (te, nad którymi nie masz kontroli), utracą swoje procedury obsługi zdarzeń.
Jeśli nie martwisz się tym, zachowanie referencji do modułu obsługi zdarzeń powinno być wystarczające. Jeśli martwisz się skutkami ubocznymi utraty obiektów obsługi obiektów przez inne obiekty, możesz przemyśleć swoją strategię buforowania.
źródło
Jedynym sposobem, który zadziałał dla mnie, jest utworzenie zmiennej logicznej, którą ustawiłem na true podczas dodawania zdarzenia. Następnie pytam: Jeśli zmienna ma wartość false, dodaję zdarzenie.
Ta zmienna może być globalna.
źródło
zgadzam się z odpowiedzią alf, ale niewielką modyfikacją jest ,, użyć,
źródło
źródło