티스토리 뷰

반응형

InvalidOperationException은 메서드 호출이 개체의 현재 상태에 대해 유효하지 않을 때


 throw되는 예외인데 그중 스레드를 사용하여 프로그래밍시 빈번히 일어나는


"크로스 스레드 작업이 잘못되었습니다" 라는 오류에 대한 처리 방법입니다.



친절한 MSDN의 설명을 보면

 

Windows Forms 컨트롤에 대한 액세스는 기본적으로 스레드로부터 안전하지 않습니다.

 

컨트롤 상태를 조작하는 스레드가 두 개 이상 있는 경우 컨트롤이 일관성 없는 상태가 될 수 있습니다.

 

경합 상태, 교착 상태 등의 다른 스레드 관련 버그가 발생할 수 있습니다.

 

 따라서 컨트롤에 대한 액세스가 스레드로부터 안전한 방식으로 수행되는지 확인해야 합니다.


라고 설명되어 있습니다.



윈폼 컨트롤들이 자체적으로 가지는 스레드와 사용자에 의해 동작하는 스레드의 충돌을 처리하기


위함인데요.  위의 MSDN군의 말처럼 동시에 두개의 스래드가 컨트롤을 작업해버리면 아작(?)나는


경우가 생기겠지요.. -ㅅ-a



그리하여 Invoke라는 매소드를 사용하여(컨트롤들은 대부분 invoke 매소드가 다있습니다.)


사용자 스레드의 작업을 해당 컨트롤의 스레드에 인계하여 크로스 스래드오류를 처리하게 해줍니다.


크로스 스래드에 대한 오류는 CheckForIllegalCrossThreadCalls 프로퍼티를 조작하여 오류가


발생하지 않게  할 수도 있습니다. (false를 주면 크로스 스래드 오류가 나지않습니다.

1.0에서는 디폴트가 false였고 2.0은 true입니다.)


하지만 CheckForIllegalCrossThreadCalls를 false로 하여 크로스 스래드오류를 무시하고


프로그래밍을 할경우 잠재적인 오류에 X고생 할수 있으니 권장사항인 true로 하도록 합시다 ^^a



아래의 Writetext 함수는 textBox3의 Text를 변경하는invoke예제 함수입니다.


private delegate void WritetextDelegate(string msg);

public void Writetext(string msg)

        {

            try

            {

                if (this.InvokeRequired == false)

                {

                    textBox3.Text = msg;

                }

                else

                {

                    WritetextDelegate dd = new WritetextDelegate(Writetext);

                    object[] t = new object[] { msg };

                    this.BeginInvoke(dd, t);

                  //동기방식  

                  //this.Invoke(dd, t);


                }

            }

            catch (Exception er)

            {

                Console.WriteLine(er.ToString());

            }

        }

Written by Diary member
반응형
댓글