Invoke,BeginInvoke,EndInvoke

Posted 试看将来的环球,必将是代码的世界。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Invoke,BeginInvoke,EndInvoke相关的知识,希望对你有一定的参考价值。

(一)使用规则

public IAsyncResult BeginInvoke(Delegate method);
public IAsyncResult BeginInvoke(Delegate method, params object[] args);

①:传递一个委托

this.BeginInvoke(new InvokeMethod(InvokeXXX), new object[] { listDgv });

public delegate void InvokeMethod(object x);
public void InvokeXXX(object x)
{
    dgvMain.DataSource = x;
}

②:传递系统委托  public delegate void Action<T>(T obj)

this.BeginInvoke(new Action

③:传递匿名委托

算法定义

④:传递无参委托

this.BeginInvoke(new Action(()=>{
    progressBar1.Value = 0;
}));

(二)BeginInvoke,EndInvoke在异步线程中的应用

2.1 线程概述

在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行。这就需要在同一个进程中开启多个线程。我们使用C#编写一个应用程序(控制台或桌面程序都可以),然后运行这个程序,并打开windows任务管理器,这时我们就会看到这个应用程序中所含有的线程数,如下图所示。

**:如果任务管理器没有“线程数”列,可以【查看】>【选择列】来显示“线程计数”列。从上图可以看出,几乎所有的进程都拥有两个以上的线程。从而可以看出,线程是提供应用程序性能的重要手段之一,尤其在多核CPU的机器上尤为明显。

image

2.2  用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程
在C#中使用线程的方法很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一。BeginInvoke方法可以使用线程异步地执行委托所指向的方法。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用。我们可以通过四种方法从EndInvoke方法来获得返回值。

代码分析

image

关于BeginInvoke函数的分析:

image

**:在❶处有一个AsyncCallback的委托,该委托的定义为:public delegate void AsyncCallback(IAsyncResult ar),因此异步回调函数要以这个委托来进行签名调用。

BeginInvoke方法可启动异步调用。它与您需要异步执行的方法具有相同的参数,另外它还有两个可选参数。第一个参数是一个AsyncCallback 委托,该委托引用在异步调用完成时要调用的方法。第二个参数是一个用户定义的对象,该对象可向回调方法传递信息。BeginInvoke立即返回,不等待异步调用完成。BeginInvoke会返回IAsyncResult,这个结果可用于监视异步调用进度。

关于EndInvoke函数的分析:

image

EndInvoke方法检索异步调用的结果。调用BeginInvoke后可随时调用 EndInvoke 方法;如果异步调用尚未完成,EndInvoke 将一直阻止调用线程,直到异步调用完成后才允许调用线程执行。EndInvoke的参数包括您需要异步执行的方法的out和ref参数以及由BeginInvoke返回的IAsyncResult。

当我们Main()中加入Thread.Sleep(15000);等待15钟,再调用BeginInvoke(),任务管理器中线程数的变化如下图:说明在调用BeginInvoke()后系统会创建一个线程。

111

2.3 BeginInvoke和EndInvoke非阻塞式操作线程
如下图所示有这样一个UI,在执行某个耗时操作时,同时要在界面显示耗时操作运行的时间以告知终端用户。

12

代码实现

代码分析:

(三)异步调用的异常处理过程。如下图产生的异常错误信息提示到终端用户。

333

代码实现

参考资料:

如何:对 Windows 窗体控件进行线程安全调用   https://docs.microsoft.com/zh-cn/previous-versions/visualstudio/visual-studio-2010/ms171728(v=vs.100)

 

 


 

 


 

 


 


 

 

以上是关于Invoke,BeginInvoke,EndInvoke的主要内容,如果未能解决你的问题,请参考以下文章

invoke和begininvoke 区别

C#中的invoke和begininvoke

Invoke 与 BeginInvoke的区别

C#中Control的Invoke和BeginInvoke是相对于支线线程

Control.Invoke() 与 Control.BeginInvoke() [重复]

C# 多线程 Invoke BeginInvoke