C# 异步编程Invoke、beginInvoke、endInvoke的用法和作用

C# 异步编程Invoke、beginInvoke、endInvoke的用法和作用

 一、Invoke

Invoke的本质只是一个方法,方法一定是要通过对象来调用的。

一般来说,Invoke其实用法只有两种情况:

Control的Invoke

Delegate的Invoke

也就是说,Invoke前面要么是一个控件,要么是一个委托对象。

Control的Invoke

Control的Invoke一般用于解决跨线程访问的问题,比如你想操作一个按钮button,你就要用button.Invoke,你想操作一个文本label,你就要用label.Invoke,但是大家会发现很麻烦,如果我想既操作button,又操作label,能不能写在一起呢?当然可以。

我们知道,主窗体是一个Form,Form自然也是继承Control的,所以Form也有Invoke的方法,可以直接调用Form.Invoke,这就是我们常见的this.Invoke。这就是为什么有的Invoke前面啥都没有的问题,其实前面是this,只不过省略了。

示例:

this.Invoke(new Action(() =>{ button1.Text = "关闭";}));

Delegate的Invoke

Delegate的Invoke其实就是从线程池中调用委托方法执行,Invoke是同步的方式,会卡住调用它的UI线程。

void PrintMessage(string message) 
    { 
        Console.WriteLine(message); 
    } 
    MyDelegate myDelegate = PrintMessage; 
    myDelegate.Invoke("Hello, World!"); // 使用 Invoke 方法调用委托引用的方法`

beginInvoke、endInvoke

我们已经知道 C#当中 存在async/await 、BackGroudWorker类以及TPL(任务并行库)。当然C#还有一些旧的模式来支持异步编程。

    delegate long MyDel(int first, int second);
    
    class Program
    {
        static long Sum(int x, int y)
        {
            Console.WriteLine("------Inside Sum@{0}", DateTime.Now.ToString());
            Thread.Sleep(2000);
            return x + y;
        }
    
        static void Main(string[] args)
        {
            MyDel del = new MyDel(Sum);
    
            Console.WriteLine("Before BeginInvoke---@{0}", DateTime.Now.ToString());
            IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
            Console.WriteLine("After BeginInvoke@{0}", DateTime.Now.ToString());
    
            Console.WriteLine("Doing stuff@{0}", DateTime.Now.ToString());
    
            long result = del.EndInvoke(iar);
            Console.WriteLine("End Invoke@{0}", DateTime.Now.ToString());
    
            Console.WriteLine("After EndInvoke:  {0}", result);
    
            Console.ReadKey();
    
        }
    }

如上代码,定义了一个委托 MyDel ,并且在调用的时候把Sum方法传给了它的对象。一般情况下我们调用这个委托对象,它就会调用他调用列表中包含的方法。就想调用方法一样,这是同步完成的。

但是如果委托对象在调用列表中只有一个方法(引用方法),它就可以异步的去执行这个方法。BeginInovke和EndInvoke就是用来做这个事的。我们可以用如下的方式使用:

* ①当我们调用BeginInvoke方法的时候,他开始在一个独立的线程上执行引用方法,并且立即返回到原始线程。原始线程可以继续,而引用方法会在想吃的线程中并行执行。
* ②当程序希望获取已完成的异步方法的结果时,可以检查BeginInvoke返回的IAsyncResult的IsCompleted属性,或者调用委托的EndInvoke方法来等待委托执行完成。

上面的使用过程就引出的三种模式:

* ①等待-直到完成 原始线程在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等待异步方法执行完成之后再继续。

* ②轮询 ,原始线程定期检查发起的线程是否完成,如果没有则可以继续做其他的事情,

* ③回调 原始线程一直执行,无需等待或者检查发起的线程是否完成,发起的线程中的引用发放完成之后,发起的线程会调用回调方法,由回调方法在调用的EndInvoke之前处理异步方法的结果。

借鉴网站:

C#中Invoke和BeginInvoke实际应用详解_C#教程_脚本之家

C#线程委托BeginInvoke与EndInvoke的用法_C#教程_脚本之家

相关推荐

  1. Spring AMQP作用

    2024-07-10 02:06:02       32 阅读
  2. 解释Servlet过滤器作用

    2024-07-10 02:06:02       26 阅读
  3. es6 proxy作用

    2024-07-10 02:06:02       28 阅读
  4. C# - 异步编程同步编程总结

    2024-07-10 02:06:02       25 阅读
  5. 返回值作用

    2024-07-10 02:06:02       56 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 02:06:02       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 02:06:02       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 02:06:02       57 阅读
  4. Python语言-面向对象

    2024-07-10 02:06:02       68 阅读

热门阅读

  1. Go语言中的闭包函数:强大而灵活的编程工具

    2024-07-10 02:06:02       15 阅读
  2. React基础与核心概念探索

    2024-07-10 02:06:02       23 阅读
  3. 集训day3:并查集

    2024-07-10 02:06:02       22 阅读
  4. LeetCode --- 2103. Rings and Rods 解题报告

    2024-07-10 02:06:02       17 阅读
  5. 重定向(Redirect)和转发(Forward)

    2024-07-10 02:06:02       23 阅读
  6. Git:现代软件开发的基石

    2024-07-10 02:06:02       26 阅读
  7. uni-app-H5页面调用设备摄像头扫描二维码

    2024-07-10 02:06:02       24 阅读
  8. docker

    2024-07-10 02:06:02       19 阅读
  9. 【Oracle】Oracle数据库中的数据类型

    2024-07-10 02:06:02       17 阅读