콘솔에서는 await 시에 현제 쓰레드 정보가 맘대로 바뀌는데 윈폼에서는 그렇지 않았음. 비동기로 돌려놨다고 생각된것들이 UI쓰레드에서 돌면서 더 렉을 만들었음.
무슨차이인가 알아보니 현제 쓰레드가 SynchronizationContext에 잡혀있으면 await이 끝났을때 무조건 본래쓰레드로 돌아오게 처리된다고 함.
어떤절차로 쓰레드에 SynchronizationContext를 할당하는지는 못찾음.
문제는 저런게 있다고 해도 실시간으로 확인하지 않는이상 코드만 보고서 await 이후의 동기처리가 될지 비동기분기가 발생할지 명백하게 보증할수가 없다는점임.
https://blog.doosikbae.com/113
await하는 Task뒤에 ConfigureAwait(false)를 달아서 분기를 명시한다고 해도 실제 Task에 비동기적인 내용이 없으면 분기가 발생안함.
이딴식으로 경우에 따라 조사하다가 빡쳐서 관둠.
그리고 ConfigureAwait(true)를 달아서 동기처리를 명시하는것처럼 해도 이미 SynchronizationContext를 잃은상태에서는 거의 무조건적인 쓰레드 분리가 발생함. 콘솔에서는 원래 SynchronizationContext가 없으니깐 그랬음. 프로젝트 규모가 일정이상 커지면 사실상 통제불능임.
애초에 ConfigureAwait 매서드가 반환하는 ConfiguredTaskAwaitable의 문서를 보면
컴파일러용이니깐 같다쓰지말라고함.
결국 명시적인 쓰레드분리를 위해서는 Task.Run을 쓰고 명시적인 UI처리에서는 오래된 Invoke를 쓰는수밖에 없어보임.
https://stackoverflow.com/questions/26681332/why-configureawaitfalse-is-not-the-default-option
이 토픽에서는 SynchronizationContext의 존재는 언급도 없이 분기안하는게 평범한 개발자입장에서 보편적이니 기본값이니 쌉소리를 해놔서 혼란을 가중시킴.
이문제로 헤매는사람 여전히 많은듯 :
https://forum.dotnetdev.kr/t/net-console-threadpool/11660