[c#] 크로스-스레드 예외란 무엇인가

어느 스레드에서 만들어진 객체는 원칙적으로 다른 스레드에서 수정할 수 없다. 두 개 이상의 스레드들에서 동시에 하나의 객체를 수정하도록 하면 하나의 작업이 마무리되기 전에 다른 작업이 덮어써 버리는 문제가 생긴다. 이런 상황이 되면 윈도우즈는 cross-thread 예외로 처리한다. 하나의 객체를 여러 스레드들에서 동시에 읽는 건 덮어쓰고 말고 할 게 없으니 상관없다.

주로 문제되는 상황은 윈도우즈의 비주얼 컨트롤을 메인 스레드 아닌 스레드에서 수정하려 할 때다. 윈도우즈 컨트롤은 메인 스레드에서 만들어지기 때문에 원칙적으로 메인 스레드에서 수정해야 한다.

디버거는 크로스-스레드를 예외로 처리하지만 릴리스로 빌드를 하고 나면 예외로 처리되지 않는다. 실행 결과가 엉망진창이 되어 버리거나 프로세스가 멈춰 버린다. 디버거가 모든 크로스-스레드를 예외로 처리하는 것도 아니다. 그러나 디버거가 예외로 처리하지 않는다고 스레드 세이프한 건 아니다. 모르고 넘어갔다가 아무 에러 메시지 없이 프로세스가 다운되면 일이 커진다. 반대로 프로세스가 조용히 죽어 버리면 모르는 곳에서 크로스-스레드가 일어나지는 않았나 의심해 보는 게 좋다.

멀티 스레드로 구현을 할 때에는 디버거나 실행 결과를 너무 믿지 말고 크로스-스레드 상황이 아닌지 늘 염두에 두고 작업을 해야 한다.