Windows Forms의 컨트롤은 특정 스레드에 바인딩되며 스레드로부터 안전하지 않습니다. 따라서 다른 스레드에서 컨트롤의 메서드를 호출할 경우 해당 컨트롤의 호출 메서드 중 하나를 사용하여 호출을 적절한 스레드에 마샬링해야 합니다. 이 속성을 사용하면 호출 메서드를 호출해야 하는지 여부를 확인할 수 있습니다. 이 방법은 컨트롤을 소유한 스레드를 알 수 없는 경우 유용합니다.
컨트롤의 핸들이 없으면 InvokeRequired는 창 핸들이 있는 컨트롤이나 폼을 찾을 때까지 해당 컨트롤의 부모 체인을 위로 검색합니다. 적절한 핸들을 찾을 수 없으면InvokeRequired 메서드는 false를 반환합니다.
즉, 동일한 스레드에서 호출이 발생하여 Invoke가 필요하지 않거나 다른 스레드에서 컨트롤이 만들어졌지만 컨트롤의 핸들은 아직 만들어지지 않은 경우 InvokeRequired는false를 반환할 수 있습니다.
컨트롤의 핸들이 아직 만들어지지 않은 경우 컨트롤에 대한 속성, 메서드 또는 이벤트를 호출해서는 안 됩니다. 이렇게 하면 배경 스레드에서 컨트롤의 핸들이 만들어져 메시지 펌프 없이 스레드에서 컨트롤이 격리되고 응용 프로그램이 불안정해질 수 있습니다.
InvokeRequired 가 배경 스레드에서 false를 반환하면 IsHandleCreated 값을 확인하여 이러한 상황을 방지할 수도 있습니다. 컨트롤 핸들이 아직 만들어지지 않은 경우 핸들이 만들어질 때까지 기다린 후 Invoke 또는 BeginInvoke를 호출해야 합니다. 일반적으로 이러한 경우는 폼이 표시되기 전이나 Application.Run이 호출되기 전의Application.Run(new MainForm())에서와 같이 응용 프로그램의 기본 폼 생성자에서 배경 스레드가 만들어지는 경우에만 발생합니다.
다음은 멀티쓰레드간에 사용할 수 있는 몇가지 예제를 보여 줍니다.
1. 컨트롤의 InvokeRequired 속성을 이용하는 경우
if (listBox1.InvokeRequired) { listBox1.BeginInvoke(new MethodInvoker(delegate { listBox1.Items.Add(content); })); } else listBox1.Items.Add(content); }
2. Action 과 Invoke method를 이용하는 경우
Action del = delegate() { textBox1.AppendText(s + System.Environment.NewLine); }; Invoke(del);
3. Invoke method 와 무명메소드를 이용하는 경우
Invoke((MethodInvoker)delegate { textBox1.AppendText(s + System.Environment.NewLine); });
4. Invoke method와 EventHanlder 를 이용하는 경우
private void Form1_Load(object sender, EventArgs e) { new Thread(delegate() { this.Invoke(new EventHandler(displaytext)); }).Start(); } private void displaytext(object sender, EventArgs e) { richTextBox1.Text = "메시지 출력하기"; }
'C#' 카테고리의 다른 글
텍스트 로그 파일 라이브러리 - 2 (0) | 2015.02.21 |
---|---|
멀티플(multiple) 윈도우 - 1 (0) | 2015.01.24 |
Task 클래스 (0) | 2015.01.10 |
텍스트 로그 파일 라이브러리 - 1 (0) | 2015.01.09 |
ManualResetEvent 클래스 (0) | 2014.12.24 |