위 StackOverFlow 글에서 핵심적인 내용은
Do beware the very nasty threading race bug that's hidden under the floor mat,
the Elapsed event can still run after or while you call the timer's Dispose() method
timer.Elapsed 에 등록된 이벤트는 Dispose() 를 실행한 이후, 혹은 Dispose() 를 실행하는 동안
실행될 수 있다는 것이다. (이로 인해 RaceCondition 이 발생할 수 있다.)
Timer.Dispose() 는 Elapse 에 등록된 이벤트들을 제거하기 때문에, Start(), Dispose() 과정을 번갈아 거친다면
Elapse 에 같은 이벤트가 연속으로 등록될 염려는 없다.
하지만 Elapse 에 등록된 함수를 연속적으로 Start(), Dispose() 시킬 때, 해당 함수가 특정 변수를 참조한다면
해당 변수에 RaceCondition 이 발생할 가능성이 매우 높아진다.
이에 대한 해결 방법으로는
시작, 중지를 굳이 연속적으로 보장할 필요가 없는 작업에는 적절한 Delay 를 주는 방법이 있다. (after call DisPose())
Lock 을 써도 되지 않느냐고 반문할 수 있는데, 해당 문제점은 Lock 을 쓴다고 해결되지 않는다.
Lock 이 보장하는것은 어디까지나 "쓰레드의 동시 접근" 방지이다.
위 문제는 Timer 를 연속 중지, 연속 호출할 때, 한 Timer 인스턴스로 "여러개의 쓰레드" 가 생성되어
의도치 않게 한 변수에 접근될 수 있다는 문제다.
때문에 Lock 으로 "쓰레드의 동시 접근" 을 막아서 해결되지 않는다.
이 문제는 "한 Timer 당 여러 쓰레드가 생성되지 않게" 해야지 해결되는 문제이다.
'Programming > C#' 카테고리의 다른 글
[C#] SharedMemory 사용법 (0) | 2022.05.12 |
---|---|
[C#] UDP Multicast 수신 (0) | 2022.04.08 |
[C#] 반복문 캐싱 최적화 (0) | 2021.07.14 |
[C#] Task .Wait() vs await 차이점 (0) | 2021.05.04 |
[C#] StructLayoutAttribute.Pack 필드 설명 (0) | 2021.04.28 |