2016-09-05 7 views
0

ここに私の状況です:WPF:私は、コントロールの状態をチェックする必要がある状況でマルチスレッド化を行う方法

私はWPFアプリケーションを持って、私は完了する時間がかかる方法を持っています。私はUIの応答性を失いたくないので、別のスレッドでそのメソッドを呼びたいと思います。 それはあまりにも長いですので、私は代わりに私が私が扱ってる何も表してこの短いプログラムを書いた、ここに私の全体のコードを貼り付けません。

public void MainWindow() 
    { 
     InitializeComponent(); 

     ProcessThread = new Thread(TimeConsumingMethod); 
     ProcessThread.Name = "ProcessThread"; 
     ProcessThread.Start(); 

    } 


    public void TimeConsumingMethod() 
    { 
     this.Dispatcher.Invoke(() => 
     { 
      MytextBlock.Text = "new text"; 
      MyOtherTextBlock.Text = "Hello"; 
     }); 

     for (int i = 0; i < 50; i++) 
     { 
      Debug.WriteLine("Debug line " + i); 
     } 


     if (MyRadioButton.IsChecked == false) //???????????????? 
     { 
      while (true) 
      { 
       if (DateTime.Now >= timePicker.Value) 
        break; 
      } 
     } 

     OtherMethod(); 

    } 

実は、私は上記のコードには2つの質問があります: 1.私は自分のコードでUIコントロールにアクセスするたびにthis.Dispatcher.Invoke() =>....を使用する必要がありますか?つまり、私はいくつかのコントロールの状態をチェックし、Dispatcher.invokeを行う必要があるたびに(私の実際のコードで)メソッドにいくつかの場所を持っています - これらのコントロールにアクセスするより良い方法はありませんか? 2.上記のコードでは、最後にIFブロックがあります。このブロックでは、自分のRadioButtonの状態をチェックしています。そのIFの中には、時間がかかるコードがあります。ブロック場合は、これを処理するために、私のUIスレッドを言うだろう

this.Dispatcher.Invoke(() => 
    { 
     if (MyRadioButton.IsChecked == false) //???????????????? 
     { 
      while (true) 
      { 
       if (DateTime.Now >= timePicker.Value) 
        break; 
      } 
     } 
    }); 

そのコードを - しかし、私はそれを望んでいない:私はこれを行うことはできません!そうすれば、このIFブロックが完了するまでUI全体がフリーズします。このような状況にどう対処すればよいですか?

+0

どのような時間がかかりますか?あなたはDb/Webからいくつかの情報を待っているのですか、いくつかのCPUを強く計算していますか? – 3615

+0

私は自分のコードに2つの時間のかかる場所があります:1.計算を続けるために特定の時間待っています。 (私が与えた例のように)2.他のメソッド()は、コンピュータの性能(CPU%、RAMなど)に関する情報を収集し、ファイルに保存します。 – Loreno

答えて

0

さて、あなたがしようとしていることを実装する方法はたくさんあります。そのうちの一つは次のようになります。

public MainWindow() { 
     InitializeComponent(); 
     Initialize(); //do some intialization 
    } 

    private async void Timer_Tick(object sender, EventArgs e) { 
     if (DateTime.Now >= timePicker.SelectedDate) { //check your condition 
      timer.Stop(); //probably you need to run it just once 

      await Task.Run(() => OtherMethod()); //instead of creating thread manually use Thread from ThreadPool 
      //use async method to avoid blocking UI during long method is running 
     } 
    } 

    private readonly DispatcherTimer timer = new DispatcherTimer(); //create a dispatcher timer that will execute code on UI thread 

    public void Initialize() { 
     MytextBlock.Text = "new text"; 
     MyOtherTextBlock.Text = "Hello"; //access UI elements normally 

     for (var i = 0; i < 50; i++) { 
      Debug.WriteLine("Debug line " + i); 
     } 

     if (MyRadioButton.IsChecked == false) 
     { 
      timer.Interval = TimeSpan.FromSeconds(10); // during init setup timer instead of while loop 
      timer.IsEnabled = true; 
      timer.Tick += Timer_Tick; //when 10 sec pass, this method is called 
      timer.Start(); 
     } 
    } 

    public void OtherMethod() { 
     //long running method 
     Thread.Sleep(1000); 
    } 

私はいくつかのコメントを追加しましたが、主なアイデアはこれです:

  1. は、手動でスレッドを作成しないでください、

  2. ThreadPoolの使用しますタイマーを使用して定期的にチェックします。

  3. I/Oタスクがあるときに非同期メソッドを使用します。

+0

ループを使用すると何が問題になりますか?私の例のように)設定された時間を待つ? – Loreno

+0

少なくとも、あなたのスレッドをループの中でスリープ状態にする必要があります。そうしないと、大量のCPU時間が消費されます。タイマーはあなたがやっていることに対して正確に作成され、コードをより明示的にします。 [this](http://stackoverflow.com/q/2822441/5246145)の質問を参考にして、より多くの意見を得てください。 – 3615

関連する問題