poy*_*poy 5 .net invoke invokerequired
我一直看到/使用代码的某种形式或方式:
public void method1(Object sender, EventArgs args)
{
if(dataGridView1.InvokeRequired)
dataGridView1.Invoke(new EventHandler(method1), null);
else
// Do something to dataGridView1
}
Run Code Online (Sandbox Code Playgroud)
我的问题是......当我使用时,GUI线程会发生什么Invoke?它是否像一个中断,线程将立即执行method1?
是不是像中断一样...
一点都不。当线程忙于执行代码时,没有安全的方法可以中断该线程。这会导致一种特别令人讨厌的问题,称为“重入错误”。这是固件程序员在嵌入式系统上实现中断处理程序时要面对的错误。本网页中有一些相关背景信息。
程序的 UI 线程以不同的方式解决了这个问题,它在生产者-消费者问题的标准解决方案中扮演消费者的角色。成分是生产者将消息发布到的线程安全队列和消费者线程中的调度程序循环。它从队列中检索消息并执行与该消息关联的消息处理程序。这通常被描述为“泵送消息循环”。生产者最常见的是操作系统,为用户按下按键或移动鼠标等事件生成消息。但它可以是生成消息的任何代码,包括另一个线程。
Winforms 向该方案添加了一个附加队列,即调用队列。它存储您的代码创建的委托对象以及您提供的参数。Begin/Invoke 将一个条目添加到调用队列并调用 PostMessage() 以让 UI 线程知道需要执行某些操作。
如果 UI 线程正忙于执行代码(例如处理绘制事件),那么它就会忽略这一点。它不会注意到已发布的消息,直到它再次空闲,重新进入调度程序循环并调用 GetMessage()。或者它已经空闲了,它会很快回复消息。它检索调用队列中的条目并执行委托目标。
如果使用 Invoke 而不是 BeginInvoke,它将调用队列条目中 ManualResetEvent 的 Set() 方法。您的线程正在等待,然后它将恢复执行。如果委托方法失败,那么此时引发的异常也将在线程中重新引发。
您可以从其工作方式中得出一些基本结论:
| 归档时间: |
|
| 查看次数: |
284 次 |
| 最近记录: |