C#中begininvoke与invoke

来源:互联网 发布:指针 数组 区别 联系 编辑:程序博客网 时间:2024/05/17 09:45

    

invoke或者BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数


址,因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这


些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线


程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所


属的控件,那么将会产生竞争条件,造成不可预料的结果。

    使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面


线程发送消息,是一个同步方法。也就是说在Invoke封送的方法被执行完毕前Invoke


方法不会返回,从而调用者线程将被阻塞。


     使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这


个异步方法。也就是该方法封送完毕后马上返回,不会等待委托方法的执行结束,调


用者线程将不会被阻塞。但是调用者也可以使用EndInvoke方法或者其它类似


WaitHandle机但是在内部实现上,Invoke和BeginInvoke都是用了PostMessage方


法,从而避免了SendMessage带来的问题。而Invoke方法的同步阻塞是靠


WaitHandle机制来完的。

        


如果你的后台线程在更新一个UI控件的状态后不需要等待,而是要继续往下处理,那么


你就应该使用BeginInvoke来进行异步处理。


如果你的后台线程需要操作UI控件,并且需要等到该操作执行完毕才能继续执行,那么


你就应该使用Invoke。否则,在后台线程和主截面线程共享某些状态数据的情况下,如


果不同步调用,而是各自继续执行的话,可能会造成执行序列上的问题,虽然不发生死


锁,但是会出现不可预料的显示结果或者数据处理错误。


      可以看到ISynchronizeInvoke有一个属性,InvokeRequired。这个属性就是用


来在编程的时候确定,一个对象访问UI控件的时候是否需要使用Invoke或者


BeginInvoke来进行封送。如果不需要那么就可以直接更新。在调用者对象和UI对象同


属一个线程的时候这个属性返回false。在后面的代码分析中我们可以看到,Control类


对这一属性的实现就是在判断调用者和控件是否属于同一个线程的。


转自:http://www.cnblogs.com/zhangchenliang/p/4953649.html