시나리오가 있습니다. (Windows Forms, C #, .NET)
- 일부 사용자 정의 컨트롤을 호스팅하는 기본 양식이 있습니다.
- 사용자 정의 컨트롤은 무거운 데이터 작업을 수행하므로
UserControl_Load
메서드를 직접 호출하면 로드 메서드 실행 기간 동안 UI가 응답 하지 않습니다 . - 이것을 극복하기 위해 다른 스레드에 데이터를로드합니다 (기존 코드를 가능한 한 적게 변경하려고 시도 함)
- 데이터를로드 할 백그라운드 작업자 스레드를 사용했으며 완료되면 응용 프로그램에 작업이 완료되었음을 알립니다.
- 이제 진짜 문제가 생겼습니다. 모든 UI (기본 양식 및 해당 하위 사용자 컨트롤)는 기본 기본 스레드에서 작성되었습니다. usercontrol의 LOAD 메소드에서 userControl의 텍스트 상자와 같은 일부 컨트롤 값을 기반으로 데이터를 가져옵니다.
의사 코드는 다음과 같습니다.
코드 1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
그것이 준 예외는
교차 스레드 작업이 유효하지 않음 : 작성된 스레드 이외의 스레드에서 액세스 한 제어.
이것에 대해 더 많이 알기 위해 인터넷 검색을했고 다음 코드를 사용하는 것처럼 제안이 나왔습니다.
코드 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be binded to grid at some later stage
}
}
그러나 그러나 나는 ... 다시 광장으로 돌아온 것 같습니다. 응용 프로그램이 다시 응답하지 않게됩니다. 조건 1 번 라인의 실행으로 인한 것 같습니다. 로딩 작업은 부모 스레드에 의해 다시 수행되며 내가 생성 한 세 번째 스레드는 아닙니다.
나는 이것이 옳은지인지 아닌지를 알지 못한다. 스레딩을 처음 사용합니다.
이 문제를 어떻게 해결하고 라인 # 1 if 블록의 실행 효과는 무엇입니까?
상황은 이것입니다 : 컨트롤의 값에 따라 전역 변수에 데이터를로드하고 싶습니다. 자식 스레드에서 컨트롤 값을 변경하고 싶지 않습니다. 나는 자식 스레드에서 그것을하지 않을 것입니다.
따라서 해당 데이터를 데이터베이스에서 가져올 수 있도록 값에 액세스하는 것만 가능합니다.