2016-10-28 9 views
0

こんにちは、私はUIスレッドを処理する方法を理解していないので、子スレッドで多くのUI要素を作成しようとしましたが、 ウィンドウがブロックされないように次のコードを変更する方法:メインスレッドをブロックせずに多数のコントロールを作成するにはどうすればよいですか?

public void CreateCtr(string name) 
    { 
     Button btn = new Button(); 
     btn.Content = name; 
     btn.Width = 10; 
     btn.Height = 10; 
     content.Children.Add(btn); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     int count = 100000; 
     Task.Factory.StartNew(()=> { 
      for (int i = 0; i < count; i++) 
      { 
       this.Dispatcher.BeginInvoke(new Action(()=> { 
        CreateCtr(i.ToString()); 
       })); 
      } 
     }); 
    } 
+7

真剣に、10万個のボタンを持つフォームが必要なのはなぜですか? – NineBerry

+0

実際、私はちょうどそれを行う方法があるかどうかを知りたいです。 – Joker

+0

100.000ボタンを作成することはできず、時間とは関係がありません。あなたがそれをすることを許されないという事実とは関係ありません。 –

答えて

0

UIスレッドに呼吸するためのスペースを与える必要があります。現在のコードでは、UIスレッドはすべての作成ボタンタスクを処理するためにビジー状態であり、ユーザー入力を処理することができません。それぞれのボタンを作成する間に最小限の休止を入れてください。数ミリ秒で十分です。

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    int count = 100000; 
    Task.Factory.StartNew(() => { 
     for (int i = 0; i < count; i++) 
     { 
      this.Dispatcher.BeginInvoke(new Action(() => { 
       CreateCtr(i.ToString()); 
      })); 
      Thread.Sleep(5); 
     } 
    }); 
} 

一時停止が長ければ長いほど、応答が速くなります。

フォーム上の一定量のコンポーネントの後に別のコンポーネントを追加すると時間がかかりすぎるため、しばらくしてからフォームの応答性が低下することに注意してください。これは私の元のコメントが関連するところです:フォーム上に多くのコンポーネントを持つためのユースケースはないので、フレームワークはそれをうまく処理するように設計されていません。

すべてのボタンを同じ親コンテナに配置するのではなく、各コンポーネントに100個以下の子があるコンポーネントのツリーを作成することは効果的です。しかしもう一度:私は関連するユースケースは見ません。

+0

Q:個々のボタンを作成中素晴らしい仕事ではありません、フォーム上にないボタンの配列を作成し、一度に20/50/100と言って一括して追加する方が良いでしょうか? – BugFinder

+0

@BugFinderこれはパフォーマンスが向上するとは思わないが、テストは自由です。 :)すべてのボタンを同じ親コンテナに配置するのではなく、各コンポーネントに100個以上の子を持つコンポーネントのツリーを作成することは効果的です。しかしもう一度:私は関連するユースケースを見ません – NineBerry

0

コントロールを追加するときにディスパッチャを無効にすることがあります。

int count = 100000; 
Task.Factory.StartNew(() => { 
    using (var d = Dispatcher.DisableProcessing()) 
    { 
     for (int i = 0; i < count; i++) 
     { 
      this.Dispatcher.BeginInvoke(new Action(()=> { 
       CreateCtr(i.ToString()); 
      })); 
     } 
    } 
}); 
関連する問題