• 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的真正涵义"一文中的评论

  • 相关阅读:
    CTFHub题解-技能树-Web-文件上传(00截断、双写后缀)【三】
    CTFHub题解-技能树-Web-文件上传(.htaccess、MIME绕过、文件头检查)【二】
    CTFHub题解-技能树-Web-文件上传(无验证、前端验证)【一】
    CTFHub题解-技能树-Web-SQL注入(Cookie注入、UA注入、Refer注入)【三】
    记一次centos7重启后docker无法启动的问题
    ctfshow——web_AK赛
    Windows10安装MongoDB
    centOS7安装docker和docker-compose
    xray—学习笔记
    ctfhub技能树—sql注入—过滤空格
  • 原文地址:https://www.cnblogs.com/uniquefrog/p/3772609.html
Copyright © 2020-2023  润新知