다른 스레드에서 일부 컨트롤의 속성을 가져 오려고합니다. 예를 들어.net multithreading winforms
string s = textBox1.Text;
및 안전하지 않은 스레딩에 대한 예외가 표시됩니다. 경우 은 내가
textBox1.Invoke(new MethodInvoker..blablabla
처럼, 내가 호출 전화 나에 대한 명확한를 속성을 설정하지만 때 내가 "수"로 무엇을 할 수 있는지?
다른 스레드에서 일부 컨트롤의 속성을 가져 오려고합니다. 예를 들어.net multithreading winforms
string s = textBox1.Text;
및 안전하지 않은 스레딩에 대한 예외가 표시됩니다. 경우 은 내가
textBox1.Invoke(new MethodInvoker..blablabla
처럼, 내가 호출 전화 나에 대한 명확한를 속성을 설정하지만 때 내가 "수"로 무엇을 할 수 있는지?
Invoke를 사용하지 않고도 값을 읽을 수 있지만 그렇게하지 않는 것이 좋습니다. 모든 GUI 읽기/쓰기를 메인 스레드로 중앙 집중화하십시오. 작업을 수행 할 수 있도록 필요한 모든 값을 백그라운드 스레드에 전달하십시오. 이 배경 스레드는 GUI에 관해서는 알지 못한다. 입력을 받아서 처리해야하고 GUI에 의해 해석 될 수 있도록 Invoke
메소드를 사용하여 전달 된 결과를 생성해야한다. 이것은 재사용을위한 것입니다. 내일 콘솔 API 나 WPF 같은 다른 GUI로 전환한다고 상상해보십시오. 백그라운드 스레드 코드가 GUI 액세스와 섞여 있으면 쉽게 재사용 할 수 없습니다.
또한 으로 주 스레드에 대한 호출을 수동으로 마샬링 할 필요가 없도록 편리한 이벤트를 제공하는 BackgroundWorker을 살펴볼 수 있습니다.
당신은 얻을도에 대한 호출 사용해야합니다
string text = null;
someControl.Invoke((MethodInvoker) delegate {
text = someControl.Text;
});
스레드 친화력이 모든 작업에 영향을 미친다; 쓴다. 다른 스레드가 뭔가를 변경하는 중일 수 있습니다. 문자열의 경우 (원자 참조 읽기로 인해) 어느 방향으로 보일 지 모르지만 남용해서는 안됩니다. Invoke를 사용하십시오.
람다 구문을 사용하지 않는 이유는 무엇입니까? '() => {text = someControl.Text; } ' – Richard
@ 리차드 -이 경우 어느 쪽도 훨씬 짧지 않으므로 리더가 VS2005를 사용하는 경우에도 대리인 버전이 작동합니다. –
가능한 경우 백그라운드 스레드를 시작하기 전에 GUI 스레드에서 TextBox 값을 읽고이 값을 매개 변수로 백그라운드 스레드에 보냅니다.
일반적으로 UI와 비즈니스 논리를 구분하는 것이 바람직하며 UI 구성 요소를 인식하지 못하는 방식으로 백그라운드 작업을 설계하면 도움이됩니다.
결국 배경 스레드에서 UI 값에 액세스해야한다면 Invoke
또는 BeginInvoke
을 사용하여 TextBox에서 값을 가져올 수 있습니다.
정말하고 싶습니까? 나쁜 디자인 같아. – CodesInChaos