C# Invoke를 사용해 크로스 스레드 문제를 해결하는 방법


문제 원인




동시성이 있는 멀티 스레드 프로그램 환경에서  특정 스레드에서 생성된  Win Form 컨트롤 ( TextBox, ListView, Label, … ) 

다른 스레드에서 접근할 발생한다. 스레드에서 안전한 방식으로 컨트롤에 접근 하려면 

컨트롤을 생성한 스레드가 아닌 다른 스레드에서 윈 폼 컨트롤에 접근해야 할 때 적절한 방법으로 스레드 문제를 해결해야 한다.





해결방법




크로스 스레드 문제를 해결하는 방법은 Invoke 메소드를 사용하는 방법과 BackgroundWorker 사용하는 방법이 있다.





Invoke 구현




컨트롤에 접근하고자 하는 스레드에서 InvokeRequired 멤버 값을 가져온다.
True를 반환하면 Invoke 메소드 호출을 필요로 하는 상태고
False를 반환하면 컨트롤에 직접 접근해도 문제가 없는 상태다.


처리량이 적을경우 대리자를 따로 만들지 않고 MethodInvoke와 익명메소드를 사용하면 간결하게 코드를 작성할 수 있다.



public partial class Form1 : Form
{ 
    public Form1()
    {
        InitializeComponent();
        
        // Main 스레드 에서 생성된 컨트롤에 접근 할 또 다른 스레드 
        Thread thread = new Thread(new ThreadStart(CustomThread));
        thread.Start();
    }
    public void CustomThread()
    {
        for(int i=0; ; i++ )
        { 
            // 생성된 스레드가 아닌 다른 스레드에서 호출될 경우 true를 반환하고 정상적인 경우엔 false를 반환한다.
            if(this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate() 
                           { 
                               label1.Text = i.ToString(); 
                           })); 
            } 
            else
            {
                labe1l.Text = i.ToString();
            }
        }
    }
} 



+ Recent posts