2

コード内の兄弟。スレッドのUIコンテナ?

私は自分のWinFormsアプリケーションをマルチスレッド化しようとしています。バックグラウンドワーカーのDoWorkには、MethodInvokerデリゲートを使用してコントロールをほとんど変更しないメソッドがあります。私の質問は、私は別のスレッドから変更するたびにすべてのコントロールを呼び出さなければならないのでしょうか、複数のコントロールを呼び出すことを避けるために呼び出すことができるコントロールのコンテナがありますか?私はすべてのコントロール私は別の のスレッドからそれを変更するたびに起動するために持っているか、多分私は特定のコントロールを呼び出し、複数の を避けるために呼び出すことができるコントロールのコンテナのいくつかの種類がある場合

+0

あなたは可能性があり、単に 'あなたが必要なコントロールのすべての更新を行うUIスレッド上のメソッドInvoke'? – DeCaf

答えて

3

呼び出しは、コントロールを所有するスレッド上で実行するようにスケジューリングすることを意味します。すべての単純なケースでは、コントロールのすべてと同じスレッドになります。したがって、コントロールとやりとりしたいときはいつでも呼び出す必要がありますが、実際には一緒に欲しいだけのインタラクションを「プール」することができます(より効果的になるように)。

呼び出しを「非表示」にするには、トリガされたときにそのプロパティの変更を検出し、これらのプロパティに応じてコントロールと対話するコードのInvokeを使用するクラスを作成する必要があります。したがって、ワークフローは次のようになります。

  1. 作業者は、呼び出さずに「コントローラ」のプロパティを変更します。これは即座の効果はありません。
  2. コントローラは、ある時点で(たぶん作業者によって定期的に)トリガされます。
  3. コントローラは、プロパティの変更内容とコントロールの呼び出しコードへの変換方法を検出します(または既に知っています)。これは、それに応じてコントロールと対話するコードのブロックを呼び出します。
0

私の質問はありますか?

UIを変更するたびに呼び出す必要があります。呼び出し操作は、1つのperoeprtyを変更する以上のことを行うことができます。これは、100個のコントロールを完全な関数にすることができます。

パフォーマンスを向上させるには、呼び出しを最小限に抑えてください。

いいえ、定義済みのコンテナはありません。例えば、匿名コードブロックのような、起動可能なプログラムであると想定されます。

0

あなたはGUIのメインパネルを言って起動した場合、その呼び出しメソッド内では、すべてその方法

以内にGUI上の他のコントロールを変更することができるように技術的には、すべてのGUIのは、メインスレッド上で作成されましたあなたのバックグラウンドワーカーがメインスレッドで作成されている場合は、メインスレッドでレポートの進行状況イベントをコールバックすることができます。つまり、呼び出しは不要です。本当にバックグラウンドワーカーの主な目的。

0

2つのテキストを変更したいとします。Label。彼らは同じFormに属していると仮定すると、あなたは、いくつかの入力を保存し、パフォーマンスを向上させるために、

void buttonInvoke_Click(object sender, EventArgs e) { 
    Invoke((Action)(() => label1.Text = "A1")); 
    Invoke((Action)(() => label2.Text = "A2")); 
} 

...または単一 Invokeで、その後グループ化することで... Invokeに個々のコールのいずれかによってこれを行うことができます。

private void buttonInvoke_Click(object sender, EventArgs e) { 
    Invoke(
     (Action)(() => { 
      label1.Text = "B1"; 
      label2.Text = "B2"; 
     }) 
    ); 
} 
0
public void UpdateControl<T>(T control, Action<T> action) where T : Control 
{ 
    if(control.InvokeRequired) 
    control.Invoke(() => action(control)); 
    else 
    action(control); 
}