티스토리 뷰
[Effective C# Item 8] 이벤트 호출 시에는 null 조건 연산자(?.)를 사용하라
weekyear 2020. 10. 18. 14:12[Effective C# Item 8] 이벤트 호출 시에는 null 조건 연산자(?.)를 사용하라
이벤트를 발생 시키는 작업은 언뜻보면 그저 단순한 작업에 불과하다고 생각할지 모른다. 하지만, 이벤트에 결합된 이벤트 핸들러가 없다면 NullReferenceException이 발생한다. 이를 해결하기 위해서 이벤트 핸들러가 결합되어 있는지 확인하는 코드를 추가해주면 된다. 하지만 또 문제가 발생할 수 있다.
이벤트 핸들러의 유무 확인 후에 다른 스레드에서 이벤트 핸들러 처리에 관한 작업이 실행될지도 모르기 때문이다. 다음 예제를 통해서 더 자세히 알아보자.
간단한 이벤트 발생 코드
위 코드는 Update 이벤트에 이벤트 핸들러가 결합되어 있지 않아 실행시키면 NullReferenceException 예외가 발생한다. 이를 해결하기 위해 이벤트 핸들러가 결합되어 있는지 확인하는 코드를 작성해줘야 한다.
이벤트 핸들러 NullReferenceException 해결!...하지만,
위와 같이 작성해주면 대부분의 경우에는 잘 작동할 것이다. 하지만, 스레드 문제 때문에 결국 또 NullReferenceException이 발생할 수 있다. if 문을 통해 Updated 이벤트 핸들러 유무를 확인하여 있다고 판단한 직후, 다른 스레드에서 Updated 이벤트 핸들러 등록을 취소했다고 하면 결국 예외가 발생할 것이다.
이런 스레드 관련 버그는 잡기도 힘들고 해당 상황을 구현하는 것은 더 까다롭다. 이를 해결하기 위해서는 다음과 같이 코드를 작성하면 된다.
스레드 관련 문제도 해결!!..그래도 좀..
스레드 관련 문제를 어떻게 해결했는지 보자. handler라는 지역 변수에다가 Updated 이벤트 핸들러를 복사하는 방식으로 문제를 해결했다. 이 경우, 다른 스레드가 이벤트에 대한 구독을 취소하더라도 지역변수에 담아둔 이벤트 핸들러는 여전히 존재하기 때문에 이벤트를 발생시키는데 문제가 없다.
근데..코드 자체가 직관적으로 왜 이렇게 짜여졌는지 알기 어렵고, 모든 이벤트 핸들러에 위와 같은 코드를 작성해놓기엔 여간 복잡해 보이는게 아니다.
null 조건 연산자맨이 해결했으니 안심하라구!
null 조건 연산자(?.)는 연산자 왼쪽을 대상으로 null 체크를 하고 null이 아닐 경우 연산자 오른쪽의 표현식을 수행한다. if 문 null 체크와 다른 점은 null 체크와 메서드를 수행하는 과정이 원자적으로 수행된다는 것이다.
이 코드는 앞선 코드들과 비교해서도 멀티스레드 환경에서 안전하기도 하고 코드가 훨씬 간결하다.
멀티쓰레드 환경에서 안전하고 훨씬 간결한 null 조건 연산자(?.)를 애용하자!
멀티쓰레드 환경에서 안전한 코드를 신경쓰기는 참 어렵다. 코드를 안전하게 만들기도 어렵고 멀티 쓰레드 관련 에러 상황을 구현하기는 더 어렵기 때문이다. 그런 면에서 null 조건 연산자를 자주 쓰는 건 매우 좋은 습관인 것 같다.
참거 - Effective C# <강력한 C# 코드를 구현하는 50가지 전략과 기법, 이펙티브>, 빌 와그너, 김명신, 한빛미디어
'Programming > Effective C#' 카테고리의 다른 글
[Effective C# Item 10] 베이스 클래스가 업그레이드된 경우에만 new 한정자를 사용하라 (0) | 2020.10.18 |
---|---|
[Effective C# Item 9] 박싱과 언박싱을 최소화하라 (0) | 2020.10.18 |
[Effective C# Item 7] 델리게이트를 이용하여 콜백을 표현하라 (0) | 2020.10.18 |
[Effective C# Item 6] nameof() 연산자를 적극 활용하라 (0) | 2020.10.18 |
[Effective C# Item 5] 문화권별로 다른 문자열을 생성하려면 FormattableString을 사용하라 (0) | 2020.10.18 |