如何检测无效的控件?

时间:2011-05-14 10:06:59

标签: c# winforms invalidation

我正在实施生产者/消费者问题。代码如下所示:

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
}

2 个答案:

答案 0 :(得分:4)

Invalidate旨在触发Paint。

你需要的是Control.Invoke()你自己的刷新方法。

编辑:

您的非GUI线程甚至不应该调用Invalidate(),它们无法触及GUI。

您可以编写自己的ProcessData()表单方法,并从Prod / Cons调用mainForm.Invoke(ProcessData)

编写

然后ProcessData()负责线程安全访问数据和使GUI失效

答案 1 :(得分:1)

您可以尝试使用new关键字来自行实施Invalidate

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

Aslo Form在Ivalidate结束后触发了Invalidated事件

修改

public void InvalidateEventHandler(object sender, InvalidateEventArgs e)
{
    anotherForm.Invoke(new Action(() =>
    {
        // Do Stuff to form -- Where exception raises
    }));
}