我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#线程委托BeginInvoke与EndInvoke怎么使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#线程委托BeginInvoke与EndInvoke怎么使用

这篇文章主要讲解了“C#线程委托BeginInvoke与EndInvoke怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#线程委托BeginInvoke与EndInvoke怎么使用”吧!

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

1. BeginInovke和EndInvoke简单介绍

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方法来等待委托执行完成。

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

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

C#线程委托BeginInvoke与EndInvoke怎么使用

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

C#线程委托BeginInvoke与EndInvoke怎么使用

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

C#线程委托BeginInvoke与EndInvoke怎么使用

2.BeginInovke和EndInvoke详细

对于 BeginInvoke 方法,有几个注意的地方

① 我们可以根据上面的代码知道,BeginInvoke的参数包含如下两个部分

  • 引用方法的参数

  • CallBack参数和State参数

②BeginInvoke 会在线程池中找到一个线程,让引用方法运行在该线程上

③BeginInvoke 返回给调用线程一个实现IAsyncResult接口的对象的引用。这个接口引用包含了在线程池线程中运行的异步方法的状态。可以判断这个状态来确定异步方法是否结束。

// 3和5是引用方法参数,两个null分别是Callback参数和State参数// iar是新线程的信息IAsyncResult iar = del.BeginInvoke(3, 5, null, null);

对于 EndInvoke 方法,有几个注意的地方

①他的参数是上面BegionInvoke返回的IAsyncResult接口的引用对象,传入这个对象是便于EndInvoke去找到引用方法运行的线程。并且这个参数置于参数列表最后一个。EndInvoke提供了从异步方法调用的所有输出,包括ref和out参数。如果委托的引用方法有ref和out参数,他们必须包含在EndInvoke的参数列表当中

IAsyncResult iar2 = del2.BeginInvoke(3, 5, out res, null, null);del2.EndInvoke(out res, iar2);

②如果线程已经退出了,EndInvoke会做如下事情:

  • 清理退出的线程的状态并且释放资源

  • 找到引用方法的返回值,并作为自己的返回值

③如果EndInovke发现线程还在运行中,那么调用线程就会停止并等待,直到清理完毕并返回值。

④因为EndInvoke会去清理线程信息,所以BeginInvoke和EndInvoke必须成对使用。

⑤如果异步方法出现异常,那么在调用EndInvoke的时候会抛出异常。

3.AsyncResult类

上面说BeginInvoke方法返回了一个IAsyncResult接口的引用对象(内部是AsyncResult类的对象),AsyncResult类型表现了异步方法的状态。下面是这类的主要组成部分:

C#线程委托BeginInvoke与EndInvoke怎么使用

C#线程委托BeginInvoke与EndInvoke怎么使用

4.三种模式

① 等待-直到完成 (比较简单的模式)

//开始执行异步方法IAsyncResult iar = del.BeginInvoke(3, 5, null, null);//Do Something 耗时del2.EndInvoke(iar);

像上面的代码,BeginInvoke之后,做了一些事情,然后调用EndInvoke来处理结果,这种方式就是等待-直到完成的模式。

②轮询模式

轮询模式中,原始的线程发起了异步的方法调用,做一些事情,然后使用IAsyncResult中的IsComplete熟悉来定期检查开启的线程是否完成。如果未完成就在去做一些其他事情。

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(200);        return x + y;    }    static void Main(string[] args)    {        MyDel del = new MyDel(Sum);        //开始执行异步方法        IAsyncResult iar = del.BeginInvoke(3, 5, null, null);        //轮询开始        while (!iar.IsCompleted)        {            //未完成,执行下面的语句            for (long i = 0; i < 20000000; i++)                ;        }        //执行完成调用EndInvoke获取结果        long result = del.EndInvoke(iar);        Console.ReadKey();    }}

③回调模式

前两种都是主动方式的,原始线程一直在监控这新开启的线程。但是回调是被动的,一旦原始线程发起了异步方法,它就自己管自己了,不在考虑同步。

当异步方法调用结束之后,系统调用一个用户自定义的方法来处理结果,并且调用委托的EndInvoke方法。这个用户自定义的方法就是回调方法。

上面的BegionInvoke中写过,他会有两个参数一个Callback参数和一个State参数.

CallBack参数:是回调方法的名称。

State参数:可以是null,或者传入回调方法的一个对象的引用。我们可以用IAsyncResult参数的AsyncState属性来获取这个对象,参数的类型是object。

C#线程委托BeginInvoke与EndInvoke怎么使用

a.回调方法:

回调方法的签名和返回类型必须和 AsyncCallback委托类型所描述的形式一致。

C#线程委托BeginInvoke与EndInvoke怎么使用

两种方式,构建这个AsyncCallback参数

new AsyncCallback 对象  

IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone),null);

直接传回调方法的名称

IAsyncResult iar = del.BeginInvoke(3, 5, CallWhenDone, null);

其中 CallWhenDone 如下:

static void CallWhenDone(IAsyncResult iar){    AsyncResult ar = (AsyncResult)iar;    MyDel del = (MyDel)ar.AsyncDelegate;    //回调方法中调用了EndInvoke    long result = del.EndInvoke(iar);}
b.在回调方法中调用EndInvoke

上面代码中,在回调中使用了EndInvoke,上文中说到 EndInvoke的调用,是委托的调用,并且需要传入一个IAsyncResult的接口对象的引用。

所以想要在回调方法里面,调用这个EndInvoke,就得拿到两个东西一个是委托对象、一个是IAsyncResult,由于我们AsyncCallback委托本身就是必须要传入IAsyncResult 的,所以这个比较容易,剩下的就是委托对象本身了。在AsyncResult类小节里面我看到,它里面存着一个 AsyncDelegate(它就是委托对象的引用),还有就是 IAsyncResult接口对象在内部就是AsyncResult类对象。所以才可以像上main的代码,通过强制类型转换得到MyDel的对象。

C#线程委托BeginInvoke与EndInvoke怎么使用

第二种方法就是如果State参数没有用处,可以通过State参数,把委托的对象传过去。

调用的地方,最后一个参数传入del

IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone),del);

回调方法:

static void CallWhenDone(IAsyncResult iar){    MyDel del = (MyDel)iar.AsyncState;    long result = del.EndInvoke(iar);}

感谢各位的阅读,以上就是“C#线程委托BeginInvoke与EndInvoke怎么使用”的内容了,经过本文的学习后,相信大家对C#线程委托BeginInvoke与EndInvoke怎么使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#线程委托BeginInvoke与EndInvoke怎么使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#线程委托BeginInvoke与EndInvoke怎么使用

这篇文章主要讲解了“C#线程委托BeginInvoke与EndInvoke怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#线程委托BeginInvoke与EndInvoke怎么使用
2023-07-02

C#委托怎么使用

这篇文章主要介绍了C#委托怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#委托怎么使用文章都会有所收获,下面我们一起来看看吧。1、什么是委托从数据结构来讲,委托是和类一样是一种用户自定义类型。委托是方
2023-06-29

C#如何使用异步委托开启线程

这篇文章主要为大家展示了“C#如何使用异步委托开启线程”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#如何使用异步委托开启线程”这篇文章吧。异步委托开启线程 public static voi
2023-06-17

C#异步委托和多线程怎么理解

这篇文章主要讲解了“C#异步委托和多线程怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#异步委托和多线程怎么理解”吧!关于这个问题,我想很多初学者跟我一样有很多疑问吧。下面我说的内
2023-06-18

C#中怎么使用委托和事件

在 C# 中,委托和事件是一种常用的机制,用于实现事件驱动的编程模型。委托是一种类型,用于存储对方法的引用,而事件是委托的一种特殊用法,用于通知其他代码发生了某个特定的动作。下面是一个简单的示例,演示了如何在 C# 中定义和使用委托和事件
C#中怎么使用委托和事件
2024-03-06

C#中的委托怎么声明和使用

这篇“C#中的委托怎么声明和使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#中的委托怎么声明和使用”文章吧。如果要给方
2023-06-30

怎么在c#中利用委托事件实现多线程通信

本篇文章为大家展示了怎么在c#中利用委托事件实现多线程通信,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。在研究c# 线程之间通信时,发现传统的方法大概有三种:全局变量,由于同一进程下的多个进程之间共
2023-06-14

C#中委托的概念与使用方法是什么

本篇内容主要讲解“C#中委托的概念与使用方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#中委托的概念与使用方法是什么”吧!委托的概念委托这个名字取的神乎其神的,但实质是函数式编程,把
2023-07-05

C#线程池ThreadPool怎么使用

这篇文章主要讲解了“C#线程池ThreadPool怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#线程池ThreadPool怎么使用”吧!一、ThreadPool概述提供一个线程池
2023-07-02

c语言怎么使用多线程

什么是多线程?多线程是一种并发编程技术,允许程序同时执行多个任务或线程。c 语言使用 posix 线程库创建和管理线程,步骤如下:创建线程加入线程线程函数同步(使用互斥锁、条件变量和信号量)注意:共享数据时使用同步机制。错误处理对于多线程编
c语言怎么使用多线程
2024-05-21

C++中std::thread线程怎么使用

本篇内容主要讲解“C++中std::thread线程怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++中std::thread线程怎么使用”吧!1:std::thread的基本用法最简
2023-07-04

C#异步多线程ThreadPool怎么使用

这篇文章主要讲解了“C#异步多线程ThreadPool怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#异步多线程ThreadPool怎么使用”吧!启动线程池线程ThreadPool
2023-06-25

C#线程绑定ThreadLocal类怎么使用

本篇内容主要讲解“C#线程绑定ThreadLocal类怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#线程绑定ThreadLocal类怎么使用”吧!在.Net 4.0的Thread里,
2023-07-02

C++中标准线程库怎么使用

本文小编为大家详细介绍“C++中标准线程库怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++中标准线程库怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.创建线程异步执行我们可以通过async
2023-06-29

C#中单例模式与多线程怎么用

这篇文章给大家分享的是有关C#中单例模式与多线程怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、单例模式我们先来看看两种创建单例模式的示例代码。1、饿汉式 饿汉式创建单例模式是在程序里面直接初始化了一个对
2023-06-29

Linux pthread线程怎么创建与使用

本篇内容介绍了“Linux pthread线程怎么创建与使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.前言线程与进程的区别 (1)进
2023-06-29

C#怎么使用CallContext缓存线程数据

本篇内容主要讲解“C#怎么使用CallContext缓存线程数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#怎么使用CallContext缓存线程数据”吧!一、CallContext 概述
2023-06-30

C#怎么使用LOCK实现线程同步

本篇内容介绍了“C#怎么使用LOCK实现线程同步”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、简介线程安全概念:线程安全是指在当一个线程
2023-06-30

C#怎么使用Monitor类实现线程同步

这篇文章主要讲解了“C#怎么使用Monitor类实现线程同步”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#怎么使用Monitor类实现线程同步”吧!一、简介Lock关键字是Monitor
2023-06-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录