잠금 (예 : 중요 섹션) 내부에서 발생하는 이벤트는 교착 상태에 빠지기 쉽습니다. 이는 이벤트 처리기가 일부 비동기 작업에서 차단해야 할 수도 있기 때문입니다 같은 자물쇠를 사십시오..NET 이벤트 발사 및 처리에 대한 모범 사례
가 잠금 내부 이벤트를 발생하기 위해 필요한 경우후 항상 비동기 이벤트를 발생 : 자, 디자인 현명한 내 마음에 와서 두 가지 가능한 솔루션이 있습니다. 예를 들어, 이벤트 발사 순서가 중요하지 않은 경우 ThreadPool을 사용하여이 작업을 수행 할 수 있습니다. 이벤트의 순서를 보존해야하는 경우 단일 이벤트 실행 스레드를 사용하여 순서대로 이벤트를 시작하지만 비동기 적으로 시작할 수 있습니다.
이벤트를 발생시키는 클래스/라이브러리는 교착 상태를 방지하고 잠금 내에서 이벤트를 시작하기 위해 필요한 예방 조치를 취할 필요가 없습니다. 이 경우 이벤트 핸들러 내부에서 잠금 (또는 다른 차단 조작)을 수행하는 경우 비동기 적으로 이벤트를 처리하는 것은 이벤트 핸들러의 책임입니다. 이벤트 처리기가이 규칙을 따르지 않으면 교착 상태가 발생할 경우에 대비해야합니다.
솔직히 두 번째 옵션은 이벤트 처리기 또는하지 않을 수 있습니다 무엇을 추측해야하는 이벤트 발사 코드와 같은 원리의 분리 측면에서 더 낫다고 생각합니다.
그러나 실제적으로 두 번째 옵션은 모든 이벤트 처리기가 모든 이벤트 처리 코드를 비동기식으로 실행해야하는 시점으로 수렴되는 것 같으므로 첫 번째 경로를 택할 것입니다. 대부분의 경우에는 일부 일련의 호출이 차단 작업을 수행하는지 여부를 결정합니다. 복잡한 이벤트 처리기의 경우 가능한 모든 경로를 추적하고 코드가 전개됨에 따라 경로를 추적하는 것은 쉬운 일이 아닙니다. 따라서 문제를 한 곳에서 해결하는 것이 바람직합니다.
간과 할 수있는 다른 대체 솔루션이 있는지, 그리고 가능한 장점/단점과 함정이 각각의 가능한 해결책에 기인하는지 보는 데 관심이 있습니다.
이런 상황에서 가장 좋은 방법이 있습니까?
나는 또 다른 가능한 솔루션이라고 확신합니다. 이벤트를 발생시키는 메서드가 이벤트를 발생시키는 메서드를 잠그고 있는지 여부를 간단하게 확인할 수는 있지만 이벤트 호출 메서드로 이어지는 호출 체인에서 호출 메서드 중 하나가 호출되는지 여부를 확인하는 것은 일반적으로 매우 어렵거나 불가능합니다. 이미 자물쇠가 있습니다. 이러한 경우 잠금 컨텍스트 외부에서 이벤트를 시작하는 것은 매우 어렵습니다. BCL은 관련 예제이지만 BCL은 독립적이고 (일반적으로 작고 스레드 안전하지 않은) 클래스의 모음이기 때문에 복잡한 비즈니스 로직이있는 응용 프로그램 코드에 적용 할 수 있는지 확실하지 않습니다. – exc
@exc 맞습니다 : 코드가 잠긴 영역에서 잠금 및 딥 콜 스택을 많이 사용하는 경우 큰 문제입니다. 그런 정교한 스레딩 코드가 정말로 최고의 솔루션인지 재평가해야한다고 제안하고 싶습니다. 특히 교착 상태가 수동 조작없이 앱이 절대로 회복되지 않는다는 가장 치명적인 오류라고 생각하면됩니다. 귀하의 경우에는 콜백 호출을 스레드 풀로 푸시하는 것이 안전하고 쉽습니다. 이것은 나의 새로운 대답이다. – usr
답변을 제출해 주셔서 진심으로 감사 드리며 원칙적으로 귀하와 동의한다는 사실을 지적하고 싶습니다. 관리하기 어려운 코드를 작성하지 않으려 고 노력합니다. 그러나 이러한 이상적인 접근 방식은 대용량 코드베이스 (수백만 줄의 코드)가있는 경우 거의 적용 할 수 없다는 점을 명심하십시오. 대부분의 코드는 수십 명의 사람들이 작성했으며 현재 최소한 15 명으로 이루어진 그룹. 나는 점진적으로 코드를 개선하려고 노력하고 있으며, 따라서 내 질문을한다. – exc