2009-07-10 20 views
26

同じプロセスから2つ(またはそれ以上)のWPFウィンドウを作成する必要があります。しかし、ウィンドウは、互いにブロックすることができないはずなので、別々のスレッドで処理する必要があります。これはどうすればいいですか?リサイズでWPFウィンドウを個別のスレッドに作成して表示するにはどうすればよいですか?

これをすることによって達成される:

  • 新しいスレッドがパラメータ
  • としてフォームを持つ新しいスレッド

  • コールApplication.Runからフォームを作成

    • スタートしかし、どのように私はWPFで同じことをするのですか?

  • 答えて

    40

    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(); 
    } 
    

    EDIT: これは古い答えですが、それは頻繁に訪れているように見えることから、私はまた、以下の修正/改善(テストしていない)と考えることができます。

    あなたは、そのようなウィンドウを閉じるだけで、スレッド(代理人)の外側から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()

    +3

    私はこの方法で作成したウィンドウを閉じることができますどのように偉大な –

    +0

    私はまだそれは古い質問です知っているが、このアプローチ。?私はちょうど1つの問題を持っています - 私はそれを使用してウィンドウをロードしています - 新しいスレッドでウィンドウをロードすることを示します - > stuff - > newThread.Abort()そしてそれは大丈夫です。 – MajkeloDev

    +0

    こんにちは、私もこれで苦労していました。私にとって、この[リンク](https://dontpaniclabs.com/blog/post/2013/11/14/dynamic -splash-screens-in-wpf /)が動作しました。これはManualResetEvent-wayを使用しています。チェック(GitHub) – dba

    2

    と答えていると思います。このquestionのJon Skeetの答えを見てください。私が探していたまさに

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

    オオプスへ、遅く、ありがとうkek444。 –

    1

    基本的に、あなたのスレッドのstartメソッドで次のように行います。

    私はこのかかわらず、同じようにそれをやっている:

    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(); 
         } 
        } 
    

    MainWindow.Xaml.cs

    public partial class MainWindow : Window 
    { 
        public MainWindow(Thread splashWindowThread) 
        { 
         InitializeComponent(); 
    
         MyInializaComponent(); 
    
         splashWindowThread.Abort(); 
        } 
    
    //void DoStuff(){}; 
    } 
    

    私は後に離れて行くために私のスプラッシュ画面を必要とプログラムはすべての読み込みを完了しました。

    9

    この回答はGoogleが提供した最初の結果であるため、価値があります。私はまた、Eugene Prystupa's Weblogから取ら以下を追加したいと思います:私たちの簡素化ソリューションへの1つのキャッチがある」

    を特定のウィンドウを閉じるは、このウィンドウのスレッドディスパッチャを終了し、そのスレッドは稼働し続け、後にしませんすべてのウィンドウを閉じると、プロセスは終了せずゴーストプロセスになります。[The]これに対する単純な解決策は、私たちのスレッドをバックグラウンドとしてマークすることです(thread.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(); 
    } 
    
    +1

    上記の場合の同様の参照リンク:[別のスレッドでのWPFウィンドウの起動、パート1](http://reedcopsey.com/2011/11/28/launching-a-wpf-window-in -a-separate-thread-part-1 /) –

    関連する問題