WPF의 Cross Thread 문제

2014. 7. 7. 14:48·사소한 아이의 소소한 스킬/C#

Thread를 이용하여 현재 시간을 나타내주는 프로그램.


일단, WPF 응용프로그램 프로젝트를 만든다.


그 후 XAML 코드에 간략하게 보일 TextBox를 하나 만들어 준다.


그 후 아래와 같이 코딩...

public partial class Window1 : Window
    {
        public delegate void TempDelegate();
        public TempDelegate tempDelegate;

        Timer _timer = null;

        public Window1()
        {
            InitializeComponent();
            InitTimer();
        }

        private void InitTimer()
        {
            if (_timer != null)
                return;
            TimerCallback tcb = new TimerCallback(ThreadFunc);
            _timer = new Timer(tcb, null, 0, 1000);
        }

        public void ThreadFunc(Object stateInfo)
        {
            textBox1.Text = DateTime.Now.ToString();
        }

        private void SetTextBox()
        {
            SetTextBox("-");
        }

        private void SetTextBox(string strTemp)
        {
            textBox1.Text = DateTime.Now.ToString();
        }
    }

빌드 후 실행 하면!!!!







위와 같은 에러 발생!!!


다름 아닌 Cross Thread Error...


Cross Thread Error 란..

xaml에서 만든 textbox UI를 생성한 Thread와 우리가 만든 Thread가 달라 textbox UI를 수정할 수 없는 상황에서 발생 하는 에러!!


즉, 내가 생각하기로는 WPF는 STA( Single Thread Application )이다. 

WPF의 UI는 WPF의 메인 Thread에서 모두 생성한다.!! 그리하여 UI의 값들을 변경하고자 할때 따로 생성한 Thread에서는 수정할 수 없고 메인 Thread에서만 수정이 가능하다!


라고 생각하고 정의하고 있습니다.! ( 만약 다르다면... 댓글 남겨주세요..ㅠㅠ )


그리하여 상단의 ThreadFunc 에서 textBox에 접근하는 것은 Cross Thread Error 라는 것 !


이러한 문제를 막기 위해 내가 생성한 Thread에서 UI에 접근하여 수정 시 WPF의 메인 Thread에게 UI의 값을 수정 해달라고 요청을 해야 한다는 것..!! 그리하여 나타난 것이 Dispatch의 invoke, begininvoke..!!


사용 방법은 아래와 같다..


    public partial class Window1 : Window
    {
        public delegate void TempDelegate();
        public TempDelegate tempDelegate;

        Timer _timer = null;

        public Window1()
        {
            InitializeComponent();
            InitTimer();
        }

        private void InitTimer()
        {
            if (_timer != null)
                return;
            TimerCallback tcb = new TimerCallback(ThreadFunc);
            _timer = new Timer(tcb, null, 0, 1000);
        }

        public void ThreadFunc(Object stateInfo)
        {
            if (this.Dispatcher.Thread != Thread.CurrentThread)
            {
                tempDelegate += new TempDelegate(SetTextBox);
                Dispatcher.Invoke(DispatcherPriority.Normal, tempDelegate);
            }
        }

        private void SetTextBox()
        {
            textBox1.Text = DateTime.Now.ToString();
        }
    }

위와 같이 작성하면 문제가 일어나지 않는다..!!


작성된 코드에서


if (this.Dispatcher.Thread != Thread.CurrentThread)

위 문은 this.Dispactcher.Thread와 Thread.CurrentThread가 같지 않다.


즉, 메인 Thread와 내가 생성한 Thread가 다를 시에는!!


아래의 구문을 사용한다라는 뜻!!

     tempDelegate += new TempDelegate(SetTextBox);
     Dispatcher.Invoke(DispatcherPriority.Normal, tempDelegate);

Delegate를 생성하여 실행할 함수를 지정해주고 지정한 Delegate를 Invoke로 실행해주어


Cross Thread를 방지하는 것이다..


위 예제는 Invoke만 했는데 BeginInvoke로도 가능하다.. 예제는 다음 포스팅에서.......



2014/06/09 - [Skill/C#] - WPF의 Cross Thread BeginInvoke 방법



저작자표시 비영리 변경금지 (새창열림)
'사소한 아이의 소소한 스킬/C#' 카테고리의 다른 글
  • WPF에서의 Console 이용법
  • WPF의 Cross Thread BeginInvoke 방법
  • WPF Window Show, Hide, Close
  • 여러 생성자를 만들때 팁.
JOOJI
JOOJI
그냥 혼자좋아하는 것들 남기는 블로그....
  • JOOJI
    사소한프로그래머의 소소한행복
    JOOJI
  • 전체
    오늘
    어제
    • 분류 전체보기 (966) N
      • 사소한 아이의 소소한 일상 (247)
      • 사소한 아이의 소소한 먹거리 (44)
      • 사소한 아이의 소소한 정보 (75) N
      • 사소한 아이의 소소한 감사 (4)
      • 사소한 아이의 소소한 운동 (65) N
      • 사소한 아이의 소소한 여행 (40)
        • 2013_전주 (1)
        • 2014_독일 (13)
        • 2014_군산 (1)
        • 2015_제주도 (3)
        • 2015_서울모토쇼 (3)
        • 2015_진해 (1)
        • 2015_전주 (1)
        • 2016_여수 (1)
        • 2020_강릉 (1)
        • 2022_제주도 (4)
      • 사소한 아이의 소소한 강짱 (22)
        • 하트투하트 (10)
        • MAPS (1)
        • 화려한 유혹 (2)
        • 한여름의 추억 (2)
      • 사소한 아이의 TV (50)
        • Drama (9)
        • 예능 (32)
        • 사소한 아이의 다현 (9)
      • 사소한 아이의 소소한 스킬 (130)
        • Scaleform (2)
        • C# (74)
        • QT (3)
        • 알고리즘 (4)
        • Python (21)
        • PyQT5 (9)
        • C_C++ (2)
      • 사소한 아이의 소소한 축구 (283)
        • Korea (25)
        • Germany (45)
        • Bayern Munich (64)
        • Soccer_ETC (75)
        • Euro 2016 (12)
        • 친선경기 (3)
      • 사소한 아이의 소소한 생활정보 (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
    • 관리
  • 링크

    • 독일여행
    • 레바티스토리
    • 프라치노 공간
    • 남성패션꿀템 블로그
  • 공지사항

  • 인기 글

  • 태그

    문제
    c#
    뮌헨
    바이에른 뮌헨
    러닝
    독일
    분데스리가
    회사밥
    WPF
    python
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
JOOJI
WPF의 Cross Thread 문제
상단으로

티스토리툴바