zoukankan      html  css  js  c++  java
  • C# Invoke

    最近在看一个项目,其中用到异步进程——控件Invoke,这里将具体用法介绍如下:

    以进度条为例:

    //声明委托
    delegate void SetProgressBarEnabledDelegate(ToolStripProgressBar progressBar,bool enable);
    //运行异步进程
    this.Invoke(new SetProgressBarEnabledDelegate(SetProgressBarEnabled), new object[] { toolStripProgressBar1, p });
    //所调用的方法
     private void SetProgressBarEnabled(ToolStripProgressBar progressBar, bool enable)
            {
                if (!enable)
                {
                    toolStripProgressBar1.Value = 0;
                }
                progressBar.Enabled = enable;
            }
    

      后来查资料发现,C#中Invoke有两种,一种是控件的,一种是代理的,现将查到的区别转发如下:

    c# Invoke和BeginInvoke 区别

    (一)Control的Invoke和BeginInvoke 

    我们要基于以下认识:

    (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的。

    (2)Control的Invoke和BeginInvoke的参数为delegate,委托的方法是在Control的线程上执行的,也就是我们平时所说的UI线程。 

    我们以代码

    (一)来看

    (Control的Invoke) 

    private delegate void InvokeDelegate(); 

    private void InvokeMethod(){ 

    //C代码段

    private void butInvoke_Click(object sender, EventArgs e) { 

    //A代码段....... 

    this.Invoke(new InvokeDelegate(InvokeMethod)); 

    //B代码段...... 

    你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上 A------>C---------------->B 

    解释:

    (1)A在UI线程上执行完后,开始Invoke,Invoke是同步 

    (2)代码段B并不执行,而是立即在UI线程上执行InvokeMethod方法,即代码段C。


    (3)InvokeMethod方法执行完后,代码段C才在UI线程上继续执行。 

    看看代码(二),Control的BeginInvoke 

    private delegate void BeginInvokeDelegate(); 

    private void BeginInvokeMethod(){ 

    //C代码段

    private void butBeginInvoke_Click(object sender, EventArgs e) { 

     //A代码段....... 

    this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod)); 

    //B代码段...... 

    你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上 A----------->B--------------->C

    慎重,这个只做参考。我也不肯定执行顺序,如果有哪位达人知道的话请告知。

    解释:

    (1)A在UI线程上执行完后,开始BeginInvoke,BeginInvoke是异步

    (2)InvokeMethod方法,即代码段C不会执行,而是立即在UI线程上执行代码段B。

    (3)代码段B执行完后(就是说butBeginInvoke_Click方法执行完后),

    InvokeMethod方法,即代码段C才在UI线程上继续执行。 由此,我们知道:Control的Invoke和

    BeginInvoke的委托方法是在主线程,即UI线程上执行的。也就是说如果你的委托方法用来取花费时间长的数据,然后更新界面什么的,

    千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死。

     

    那么,这个异步到底是什么意思呢? 

    异步是指相对于调用BeginInvoke的线程异步,而不是相对于UI线程异步,你在UI线程上调用BeginInvoke ,当然不行了。

    ----摘自"Invoke和BeginInvoke的真正涵义"一文中的评论。

    BeginInvoke的原理是将调用的方法Marshal成消息,然后调用Win32 API中的RegisterWindowMessage()向UI窗口发送消息。

    ----摘自"Invoke和BeginInvoke的真正涵义"一文中的评论

  • 相关阅读:
    心得
    构建之法--界面化的简单四则运算
    构建之法--简单四则运算
    构建之法--初识Git
    构建之法---第一次作业
    【软件工程实践】结对项目-四则运算 “软件”之升级版
    第三次作业:个人项目-小学四则运算 “软件”之初版
    分布式版本控制系统Git的安装与使用
    第一次作业-准备
    字符串、文件操作,英文词率统计预处理
  • 原文地址:https://www.cnblogs.com/uniquefrog/p/3772609.html
Copyright © 2011-2022 走看看