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#教程_脚本之家

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值