Form의 컨트롤에 특정 스레드에서 접근하고자 할때, Cross-Thread 문제가 발생된다.
이런경우, 접근하고자 하는 컨트롤의 InvokeRequire 상황인지를 판단하여(즉 Thread간의
Cross되어있는경우가 있는지를 판단) 컨틀롤의 invoke를 수행시킨다.
Invoke는 동기적으로 수행된다.
사용한 예제.
Thread내에서 textbox1.text를 변경하고자 할때 Cross Thread 발생됨.
public delegate void SetTextDelegate(string szValue);
void TextFunc(string test)
{
if (textBox1.InvokeRequired)
textBox1.Invoke(new SetTextDelegate(TextUpdate), test);
else
textBox1.Text = test;
}
void TextUpdate(string szValue)
{
textBox1.Text = szValue;
}
하기는 MSDN 상세 설명이다.
Windows Forms의 컨트롤은 특정 스레드에 바인딩되며 스레드로부터 안전하지 않습니다.따라서 다른 스레드에서 컨트롤의 메서드를 호출할 경우 해당 컨트롤의 호출 메서드 중 하나를 사용하여 호출을 적절한 스레드에 마샬링해야 합니다.이 속성을 사용하면 호출 메서드를 호출해야 하는지 여부를 확인할 수 있습니다. 이 방법은 컨트롤을 소유한 스레드를 알 수 없는 경우 유용합니다.
컨트롤의 핸들이 이미 만들어진 경우 컨트롤에는 InvokeRequired 속성과 함께 스레드로부터 안전하게 호출할 수 있는 네 개의 호출 메서드( Invoke, BeginInvoke, EndInvoke, CreateGraphics)가 있습니다. 백그라운드 스레드에 컨트롤의 핸들이 만들어지기 전에 CreateGraphics를 호출하면 잘못된 크로스 스레드가 호출될 수 있습니다. 다른 스레드에서 메서드를 호출하는 경우 해당 호출 메서드 중 하나를 사용해야 합니다. |
컨트롤의 핸들이 없으면 InvokeRequired는 창 핸들이 있는 컨트롤이나 폼을 찾을 때까지 해당 컨트롤의 부모 체인을 위로 검색합니다. 적절한 핸들을 찾을 수 없으면 InvokeRequired 메서드는 false를 반환합니다.
즉, 동일한 스레드에서 호출이 발생하여 Invoke가 필요하지 않거나 다른 스레드에서 컨트롤이 만들어졌지만 컨트롤의 핸들은 아직 만들어지지 않은 경우 InvokeRequired는 false를 반환할 수 있습니다.
컨트롤의 핸들이 아직 만들어지지 않은 경우 컨트롤에 대한 속성, 메서드 또는 이벤트를 호출해서는 안 됩니다.이렇게 하면 배경 스레드에서 컨트롤의 핸들이 만들어져 메시지 펌프 없이 스레드에서 컨트롤이 격리되고 응용 프로그램이 불안정해질 수 있습니다.
InvokeRequired가 배경 스레드에서 false를 반환하면 IsHandleCreated 값을 확인하여 이러한 상황을 방지할 수도 있습니다. 컨트롤 핸들이 아직 만들어지지 않은 경우 핸들이 만들어질 때까지 기다린 후 Invoke 또는 BeginInvoke를 호출해야 합니다. 일반적으로 이러한 경우는 폼이 표시되기 전이나 Application.Run이 호출되기 전의 Application.Run(new MainForm())에서와 같이 응용 프로그램의 기본 폼 생성자에서 배경 스레드가 만들어지는 경우에만 발생합니다.
한 가지 해결책은 배경 스레드를 시작하기 전에 폼의 핸들이 만들어질 때까지 기다리는 것입니다.Handle 속성을 호출하여 핸들을 강제로 만들거나 Load 이벤트가 배경 프로세스를 시작할 때까지 기다립니다.
이에 대한 보다 나은 해결책은 스레드 간 마샬링을 위한 컨트롤 대신 SynchronizationContext에서 반환하는 SynchronizationContext를 사용하는 것입니다.
'프로그래밍 > .Net' 카테고리의 다른 글
XML 사용하여 특정 속성값 대체하기 (0) | 2014.01.17 |
---|---|
Main UI Invoke 사용 (다중 thread 속성 false) (0) | 2014.01.17 |
Process kill 하기 (0) | 2014.01.17 |
List 사용하기 (0) | 2014.01.17 |
BitConvert big endian <-> little endian 변환하기 (0) | 2014.01.17 |