InvokeRequired 属性 与Invoke方法。 收藏
zt: http://www.x2blog.cn/jinhong618/?tid=22389
在设计中为了让界面与逻辑分离,我的做法是使用事件,界面只要响应事件来处理界面的显示就行了。而事件在逻辑处理中可能由不同的线程引发,这些事件的响应方法在修改界面中的控件内容时便会引发一个异常。
这时就用到了Control.InvokeRequired 属性 与Invoke方法。
MSDN中说:
获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。
如果控件的 Handle 是在与调用线程不同的线程上创建的(说明您必须通过 Invoke 方法对控件进行调用),则为 true;否则为 false。
Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性 。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。该属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。
下面来说下这个的用法(我的一般做法):
首先定义一个委托,与这个事件处理函数的签名一样委托,当然直接使用该事件的委托也是可以的,如:
private delegate void InvokeCallback( string msg);
然后就是判断这个属性的值来决定是否要调用Invoke函数:
void m_comm_MessageEvent( string msg)
{
if (txtMessage.InvokeRequired)
{
InvokeCallbackmsgCallback = new InvokeCallback(m_comm_MessageEvent);
txtMessage.Invoke(msgCallback, new object [] { msg } );
}
else
{
txtMessage.Text = msg;
}
}
说明:这个函数就是事件处理函数,txtMessage是一个文本框。
这样就做到了窗体中控件的线程安全性。
------------------
InvokeRequired 当前线程不是创建控件的线程时为true
比如你可以自己开一个Thread,或使用Timer的事件来访问窗体上的控件的时候,在线程中窗体的这个属性就是True的。
简单的说,如果有两个线程,Thread A和Thread B,并且有一个Control c,是在Thread A里面new的。
那么在Thread A里面运行的任何方法调用c.InvokeRequired都会返回false。
相反,如果在Thread B里面运行的任何方法调用c.InvokeRequired都会返回true。
是否是UI线程与结果无关。(通常Control所在的线程是UI线程,但是可以有例外)
也可以认为,在new Control()的时候,control用一个变量记录下了当前线程,在调用InvokeRequired时,返回当前线程是否不等于new的时候记录下来的那个线程。
--------------------
我理解:如果InvokeRequired==true表示其它线程需要访问控件,那么调用invoke来转给控件owner处理。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hsgrass37301/archive/2009/10/02/4627166.aspx
分享到:
相关推荐
### C#窗体中Invoke和BeginInvoke方法详解 #### 一、为什么Control类提供了Invoke和BeginInvoke机制? 在深入探讨Invoke和BeginInvoke方法的具体用法之前,我们需要理解为什么C#中的`Control`类会提供这样的机制。...
以上代码中,`init`方法负责初始化`listView1`控件的属性,如位置、是否显示网格线、视图模式等。 #### 三、Invoke(代理名)方法的使用 在多线程程序中,为了保证UI控件的安全访问,如果当前线程不是创建控件的线程...
由于UI控件的修改必须在创建它们的线程(主线程)中进行,否则会引发“Cross-thread operation not valid”异常,因此,我们需要一种机制来安全地从后台线程与UI交互,这就是`Control.Invoke`方法的作用。...
提供了InvokeRequired属性和Invoke方法。使用这些技 巧,就可以实现我们在其他线程中直接修改界面的需要 InvokeHelper类中实现了多线程 操作窗口控件, 学习多线程的可以下载参考下。 注意: 开发环境为Visual ...
提供了InvokeRequired属性和Invoke方法。使用这些技 巧,就可以实现我们在其他线程中直接修改界面的需要 InvokeHelper类中实现了多线程 操作窗口控件, 学习多线程的可以下载参考下。 注意: 开发环境为Visual ...
当从非UI线程尝试访问UI控件时,`InvokeRequired`会检查当前线程是否是控件的所有者线程,如果不是,则需要通过`Invoke`或`BeginInvoke`方法来调度操作。 标题“InvokeRequired-NoNeed-Thread-Safe”暗示了一种方法...
在C#中,`InvokeRequired`属性用于检测当前线程是否是控件的创建线程。如果是,则可以直接操作控件;如果不是,就需要通过`Invoke`或`BeginInvoke`来异步调用UI更新的方法。这种模式在多线程程序中很常见,但每次...
为了解决这个问题,我们可以使用控件的`InvokeRequired`属性和`Invoke()`方法。 `InvokeRequired`属性用于检查当前控件是否需要在主线程上执行操作。如果返回`true`,则表示需要在主线程上执行;如果返回`false`,...
例如,可以在UI线程中安全地更新控件,通过检查InvokeRequired属性确保在正确的线程上执行UI操作。 4. 控件操作中的线程安全问题: 在多线程环境下操作UI控件时,必须注意线程安全问题。例如,在Windows窗体...
这是最常用的一种方法,通过检查 `InvokeRequired` 属性并在必要时使用 `Invoke` 方法来调用控件的方法。示例代码如下: ```csharp private delegate void EnableButtonCallBack(); private void EnableButton() {...
`SetRichTextBox`方法检查`richTextBox1`是否需要通过`Invoke`方法来调用,这取决于`InvokeRequired`属性。如果需要,则通过`Invoke`方法来调用`AppendString`委托;否则,直接更新`richTextBox1`。 ### 3. ...
5. **InvokeRequired属性**: - 在调用`Invoke`之前,应先检查控件的`InvokeRequired`属性。如果为`true`,则表明当前线程不是创建控件的线程,需要使用`Invoke`;如果是`false`,则可以直接调用控件的方法。 6. *...
3. InvokeRequired属性:这个属性用于检查当前方法是否在创建它的线程上执行。如果方法是在UI线程上创建的,但当前线程不是UI线程,则返回true。这样,开发者就可以根据这个属性来决定是直接执行方法还是通过Invoke...
每个方法内部都检查了`InvokeRequired`属性,这个属性会告诉我们是否需要在控件的创建线程(也就是UI线程)上执行操作。如果需要,我们就使用`Invoke`方法,传入一个代理,该代理将调用相同的方法,但在正确的线程...
当`InvokeRequired`属性为真时,表明当前线程不是UI线程,这时需要通过`Invoke`方法来调用`setUI`方法;反之,则直接更新控件的属性。 2. **getUI** 方法 ```csharp private void getUI(Control ctl, out string...
在实际代码中,通常会先检查`InvokeRequired`属性,如果返回`true`,说明需要在UI线程上执行当前方法,这时候就需要使用`Invoke`或`BeginInvoke`来同步或异步调用。 例如,在多线程环境下调用一个Winform窗体的`...
`InvokeRequired`属性检查是否需要在UI线程上调用方法。如果需要,它将使用闭包中的匿名方法调用`Invoke`。这样,即使在后台线程中,也能确保UI控件的安全更新。 在"WinfrmTest.zip"的代码实例中,你可能会看到一个...
任务对象处理基础结构详细信息,并提供可在任务的整个生存期内从调用线程访问的方法和属性。 例如,可以随时访问任务的 Status 属性,以确定它是已开始运行、已完成运行、已取消还是引发了异常。 状态由 TaskStatus...
如果不是,则使用`Invoke`方法和之前定义的委托`DelegateFunction`,将更新操作封装到一个在UI线程中执行的方法`SetLabelText`中。如果已经在UI线程中,就直接调用`SetLabelText`方法。 总结来说,跨线程访问控件是...
本文将深入探讨如何在C#窗体之间传递数据,主要涉及委托、属性、线程等方法。下面,我们将逐一详细解释这些方法。 1. **属性(Properties)** 在C#中,属性是一种封装机制,允许我们安全地访问类的成员变量。当...