none
[NET][TIP] Invoke를 이용하여 크로스 쓰레드 접근 관련 오류 해결법 RRS feed

답변

  • 다중 쓰레드 코드를 짜다 보면 해당 컨트롤이
    해당 쓰레드가 아닌 경우 아래와 같은 오류 메시지를 보입니다.

    "크로스 스레드 작업이 잘못되었습니다.
    TextBox1 컨트롤이 자신이 만들어진 스레드가 아닌 스레드에서

    엑세스되었습니다."

    이럴 때에는 해당 컨트롤이 만들어진 스레드에서
    함수를 다시 호출하여야 하는데요,

    아래와 같이 하면 해당 문제를 해결할 수 있습니다. 아래 예제는 새로운 쓰레드에서 TextBox로 접근하는
    예제입니다. (정확히 말하자면 새로운 쓰레드에서 TextBox가 존재하는 쓰레드로 함수를 다시 호출한다고 보시면 되겠습니다.)

    '쓰레드 생성을 위한 변수 선언
        Dim t As System.Threading.Thread
    
        '크로스 쓰레드 작업을 위한 콜백 대리자 선언
        Delegate Sub textCallBack(ByVal state As Object)
    
        '콜백 대리자 변수 선언
        Dim cbFunc As textCallBack
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            '쓰레드 생성 후 newThreadFunc 호출
            t = New System.Threading.Thread(AddressOf newThreadFunc)
    
            '쓰레드 시작 & 인수 = "Hello World"
            t.Start(CObj("Hello World"))
        End Sub
    
        Private Sub newThreadFunc(ByVal state As Object)
            If TextBox1.InvokeRequired = True Then '해당 컨트롤이 이 쓰레드에 존재하는지 확인
                'True: 해당쓰레드가 아님, 콜백
                cbFunc = New textCallBack(AddressOf newThreadFunc)
                'TextBox1 작동, 해당 컨트롤이 쓰레드에 존재하지 않으므로 새로운 컨트롤 생성.
                TextBox1.Invoke(cbFunc, New Object() {state})
            Else
                '해당 쓰레드이므로 TextBox에 접근가능
                TextBox1.Text = state.ToString()
            End If
        End Sub
    

    가끔 Visual Studio 2003 에서
    작성된 코드를 2005 에서 변환 후 실행하면, 크로스 쓰레드 오류가 발생하는 경우가

    있습니다.

    2003 처럼, 위와 같은 오류를 무시하고
    그냥 작업하는 방법은 아래의 코드를 폼로드 이벤트에 삽입해 주시면

    되겠습니다.

    CheckForIllegalCrossThreadCalls = False

    두 번째의 방법을 해결책으로 사용하는건 추천하지 않습니다..
    두 번째 방법은 임시 방편으로 사용하시길 추천합니다. ^^


    • 답변으로 표시됨 devlife 2012년 5월 28일 월요일 오전 11:42
    2012년 5월 28일 월요일 오전 11:42