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

所以现在我必须检测表单是否已失效。我查看了 Form 的事件列表,我能找到的最好的东西是绘画事件。我输入了完成工作的代码,它工作正常。问题是我以某种方式怀疑我是否以正确的方式做到了这一点,尽管它有效。我认为绘画不是做这项工作的正确地方,因为我正在做的不仅仅是绘画。我想知道是否有更好的方法来做到这一点。

编辑——无效事件处理程序的片段不起作用

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 旨在触发 Paint。

您需要的是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 has Invalidated事件,在 Ivalidate 结束后触发

编辑:

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