it-source

개별 스레드에 WPF 창을 만들고 표시하려면 어떻게 해야 합니까?

criticalcode 2023. 4. 16. 15:14
반응형

개별 스레드에 WPF 창을 만들고 표시하려면 어떻게 해야 합니까?

같은 프로세스에서2개 이상의 WPF 창을 작성해야 합니다.그러나 창은 서로 차단할 수 없기 때문에 별도의 스레드로 처리해야 합니다.이거 어떻게 해?

WinForms 에서는, 다음의 조작에 의해서 실현됩니다.

  • 새 스레드 시작
  • 새 스레드에서 양식 만들기
  • 응용 프로그램을 호출합니다.양식을 매개 변수로 사용하여 실행

WPF에서 같은 작업을 하려면 어떻게 해야 하나요?

msdn 상태:

private void NewWindowHandler(object sender, RoutedEventArgs e)
{       
    Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
    newWindowThread.SetApartmentState(ApartmentState.STA);
    newWindowThread.IsBackground = true;
    newWindowThread.Start();
}

private void ThreadStartingPoint()
{
    Window1 tempWindow = new Window1();
    tempWindow.Show();       
    System.Windows.Threading.Dispatcher.Run();
}

편집: 오래된 답변입니다만, 자주 방문하는 것 같기 때문에, 이하의 변경/개선(테스트는 실시하지 않습니다)도 생각할 수 있습니다.

이러한 창을 닫으려면 스레드 외부에서 Window 개체에 대한 참조를 유지하고(위임), 다음과 같이 창을 닫으십시오.

void CloseWindowSafe(Window w)
{
    if (w.Dispatcher.CheckAccess())
        w.Close();
    else
        w.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(w.Close));
}

// ...
CloseWindowSafe(tempWindow);

새로운 스레드가 종료(강제적으로 중단)될 수 있는 경우, 코멘트의 질문에 따라 다음을 수행합니다.

private void ThreadStartingPoint()
{
    try{
        Window1 tempWindow = new Window1();
        tempWindow.Show();       
        System.Windows.Threading.Dispatcher.Run();
    }
    catch(ThreadAbortException)
    {
        tempWindow.Close();
        System.Windows.Threading.Dispatcher.InvokeShutdown();
    }
    //the CLR will "rethrow" thread abort exception automatically
}

면책사항: 집에서 이 작업을 수행하지 마십시오. 스레드를 중단하는 것은 (대부분) 베스트 프랙티스에 위배됩니다.스레드는 다양한 동기화 기술(이 경우 단순히 호출된 기술) 중 하나를 사용하여 적절하게 처리해야 합니다.window.Close()

이 답변은 구글이 제공한 첫 번째 결과이기 때문에 그것이 어떤 것이든 상관없습니다.또한 Eugene Pristupa의 웹로그에서 다음과 같은 내용을 추가하고자 합니다.

심플한 솔루션에는 한 가지 함정이 있습니다.특정 창을 닫아도 이 창의 스레드 디스패처는 종료되지 않으므로 스레드는 계속 실행되며 모든 창을 닫은 후에는 프로세스가 종료되지 않고 Ghost 프로세스가 됩니다.[단순히] 이 문제를 해결하는 방법은 스레드를 배경(스레드 사용)으로 표시하는 것입니다.IsBackground = true;).이렇게 하면 기본 UI 스레드가 종료될 때 강제로 종료됩니다.

적절한 실장으로 디스패처가 불필요하게 되었을 때 디스패처가 정상적으로 셧다운됩니다. 다음 코드는 창이 닫힐디스패처를 종료하는 전략의 예입니다."

private void OnCreateNewWindow(object sender, RoutedEventArgs e)
{
    Thread thread = new Thread(() =>
    {
        Window1 w = new Window1();
        w.Show();

        w.Closed += (sender2, e2) =>
            w.Dispatcher.InvokeShutdown();

        System.Windows.Threading.Dispatcher.Run();
    });
        
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

답을 찾은 것 같아질문에 대한 Jon Sket의 답변을 보세요.

기본적으로 스레드 시작 방법에서는 다음과 같이 수행합니다.

private void ThreadStartingPoint()
{
    Window1 tempWindow = new Window1();
    tempWindow.Show();       
    System.Windows.Threading.Dispatcher.Run();
}

바로 내가 찾던 거야

근데 이렇게 하고 있어요

App.xaml.cs

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
            newWindowThread.SetApartmentState(ApartmentState.STA);
            newWindowThread.IsBackground = true;
            newWindowThread.Start();

            var window = new MainWindow(newWindowThread);
            window.DataContext = new MainWindowViewModel(window);
            window.Show();
        }

        private void ThreadStartingPoint()
        {
            SplashWindow tempWindow = new SplashWindow();
            tempWindow.Show();
            System.Windows.Threading.Dispatcher.Run();
        }
    }

메인 윈도Xaml.cs

public partial class MainWindow : Window
{
    public MainWindow(Thread splashWindowThread)
    {
        InitializeComponent();

        MyInializaComponent();

        splashWindowThread.Abort();
    }

//void DoStuff(){};
}

프로그램 로딩이 모두 완료된 후 스플래시 스크린이 사라져야 했습니다.

언급URL : https://stackoverflow.com/questions/1111369/how-do-i-create-and-show-wpf-windows-on-separate-threads

반응형