본문 바로가기
wpf/wpf layout 및 문법

스레드에서 UI(Window) 열기

by devjh 2020. 10. 11.
반응형

이번게시글에서는 내가 만든 스레드에서 UI를 여는방법에 대해 포스팅하겠습니다.

 

1. MainWindow.xaml

<Window x:Class="STATest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:STATest"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Grid.Column="0" Height="30" Width="80" Content="버튼" Click="Button_Click"></Button>
    </Grid>
</Window>

버튼 하나를 넣어주었습니다.

 

2. MainWindow.cs

namespace STATest
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        Thread myThread;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            myThread = new Thread(myFunc);
            myThread.Start();
        }

        private void myFunc()
        {
            MyWindow window = new MyWindow();
            window.ShowDialog();
        }
    }
}

버튼을 클릭하면 스레드를 하나 만들어주고 해당 스레드에서 Mywindow를 열어줍니다.

 

 

3. MyWindow.xaml

<Window x:Class="STATest.MyWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:STATest"
        mc:Ignorable="d"
        Title="MyWindow" Height="200" Width="400">
    <Grid>
        <TextBlock Text="성공" FontSize="40" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

MyWindow에서는 성공이라는 글자를 출력해주겠습니다.

 

 

 

4. 실행결과

버튼을 클릭하니

 

System.InvalidOperationException: '많은 UI 구성 요소에서 호출 스레드가 필요하므로 해당 스레드는 STA여야 합니다.'

the calling thread must be sta because many ui components require

 

라는 오류메시지와 함께 프로그램이 종료됩니다.

 

 

5. 해결방법

myThread = new Thread(myFunc);
myThread.SetApartmentState(ApartmentState.STA);
myThread.IsBackground = true;
myThread.Start();

스레드를 생성, 시작 사이에 두줄을 추가해줍니다.

해당스레드를 STA스레드로 설정하고, 해당 스레드를 백그라운드 스레드로 설정해줍니다.

 

UI를 담는 스레드는 STA스레드로 만들어 DispatcherObject에서 해당개체를 관리할 수 있도록 설정해줘야합니다.

(DispatcherObject에서 관리하니 외부스레드에서 내부 UI개체를 변경할때는 dispatcher 이벤트 큐를 사용해야합니다.)

 

반응형

댓글