我正在实施生产者/消费者问题。代码如下所示:
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
}
答案 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
}));
}