2

私は生産者/消費者問題を実装しています。コードは次のようになります。

void producer()
{
  // produce item
  // update some control in form
}

void consumer()
{
  // consume item
  // update some control in form
}

プロデューサーメソッドとコンシューマーメソッドは、フォームを作成したスレッドとは異なるスレッドで実行されるため、フォームのコントロールを更新できません。私は次のコードを試しました:

void producer()
{
  // produce item
  // put the work to be done in a queue
  this.Invalidate();
}

void consumer()
{
  // consume item
  // put the work to be done in a queue
  this.Invalidate();
}

そのため、フォームが無効になっているかどうかを検出する必要があります。フォームのイベントリストを調べたところ、ペイントイベントが一番良かったです。私は仕事を成し遂げたコードを入れました、そしてそれはうまく働きます。問題は、それが機能するにもかかわらず、私がこれを正しい方法で行ったことをどういうわけか疑うことです。私がやっていることはただ絵を描くだけではないので、絵の具はその仕事をするのに適切な場所ではないと思います。これを行うためのより良い方法があるかどうか疑問に思いました。

編集-無効化されたイベントハンドラーのスニペットが機能しない

public Form1()
{
  InitializeComponent();
  this.Invalidated += InvalidateEventHandler;
}
void producer(object o)
{
  // produce
  // put work in queue
  this.Invalidate();
}
public void InvalidateEventHandler(object sender, InvalidateEventArgs e)
{
  // Do Stuff to form -- Where exception raises
}
4

2 に答える 2

4

Invalidateは、ペイントをトリガーすることを目的としています。

必要なのはControl.Invoke()、フォームの独自の更新メソッドです。

編集:

GUI以外のスレッドはInvalidate()を呼び出さないでください。GUIに触れることはできません。

独自のProcessData()フォームメソッドを記述し、Prod/Cons呼び出しから作成できますmainForm.Invoke(ProcessData)

次にProcessData()、データへのスレッドセーフアクセスとGUIの無効化を担当します

于 2011-05-14T10:16:50.090 に答える
1

キーワードを使用newして、Invalidateの独自の実装を作成することができます

    public new void Invalidate()
    {
        // place your logic here
        base.Invalidate();
    }

Aslo Formは 、 Ivalidateが終了した後にトリガーされるInvalidedイベントを持っています

編集:

public void InvalidateEventHandler(object sender, InvalidateEventArgs e)
{
    anotherForm.Invoke(new Action(() =>
    {
        // Do Stuff to form -- Where exception raises
    }));
}
于 2011-05-14T10:11:34.920 に答える