C# 多线程 用委托实现异步_调用委托的BeginInvoke和EndInvoke方法

2023-05-16

1.C#中的每一个委托都内置了BeginInvoke和EndInvoke方法,如果委托的方法列表里只有一个方法,那么这个方法就可以异步执行(不在当前线程里执行,另开辟一个线程执行)。委托的BeginInvoke和EndInvoke方法就是为了上述目的而生的。

2.原始线程发起了一个异步线程,有如下三种执行方式:

方式一:等待一直到完成,即原始线程在发起了异步线程以及做了一些必要处理之后,原始线程就中断并等待异步线程结束再继续执行。

方式二:轮询,即原始线程定期检查发起的线程是否完成,如果没有则可以继续做一些其它事情。

方式三:回调,即原始线程一直执行,无需等待或检查发起的线程是否完成。在发起的线程执行结束,发起的线程就会调用用户定义好的回调方法,由这个回调方法在调用EndInvoke之前处理异步方法执行得到的结果。

3.一个控制台小程序,使用了上面三种方式,执行结果如下:


4.代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;

namespace 用委托实现异步_调用BeginInvoke和EndInvoke方法
{

    delegate long MyDel(int first,int second); //声明委托类型

    class Program
    {
        //声明委托类型的方法
        static long Sum(int x,int y) 
        {
            Console.WriteLine("                    Inside Sum");
            Thread.Sleep(200);
            return x + y;
        }

        //定义当异步线程执行结束要执行的回调函数
        static void CallWhenDone(IAsyncResult iar)
        {
            Console.WriteLine("                    Inside CallWhenDone");
            AsyncResult ar = (AsyncResult)iar;
            MyDel del = (MyDel)ar.AsyncDelegate;

            long result = del.EndInvoke(iar);
            Console.WriteLine("                    The result is {0}.", result);
        }

        //方式一:等待异步线程结束,再继续执行主线程
        static void WaitUntilDoneStyle()
        {
            MyDel del = new MyDel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //开始异步调用
            Console.WriteLine("After BeginInvoke");

            Console.WriteLine("Doing main stuff before");
            long result = del.EndInvoke(iar); //等待异步线程结束并获取结果
            Console.WriteLine("After EndInvoke:{0}", result);
            Console.WriteLine("Doing main stuff after");
        }

        //方式二:轮询检查异步线程是否结束,若没结束则执行主线程
        static void LunXunPollingStyle()
        {
            MyDel del = new MyDel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //开始异步调用
            Console.WriteLine("After BeginInvoke");

            while (!iar.IsCompleted)
            {
                Console.WriteLine("Not Done.Doing main stuff");
                //继续处理主线程事情
                for (long i = 0; i < 10000000; i++)
                    ;
            }
            Console.WriteLine("Done");
            long result = del.EndInvoke(iar); //调用EndInvoke来获取结果并进行清理
            Console.WriteLine("Result: {0}", result);
        }

        //方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)
        static void CallBackStyle()
        {
            MyDel del = new MyDel(Sum);
            Console.WriteLine("Before BeginInvoke");
            IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone), null);
            Console.WriteLine("After BeginInvoke");
            Console.WriteLine("Doing more work in main.");
            Thread.Sleep(500);
            Console.WriteLine("Done with Main. Exiting.");
        }

        static void Main(string[] args)
        {
            //方式一:等待异步线程结束,再继续执行主线程
            Console.WriteLine();
            Console.WriteLine("--------方式一:等待异步线程结束,再继续执行主线程--------");
            WaitUntilDoneStyle();

            //方式二:轮询检查异步线程是否结束,若没结束则执行主线程
            Console.WriteLine();
            Console.WriteLine("--------方式二:轮询检查异步线程是否结束,若没结束则执行主线程--------");
            LunXunPollingStyle();

            //方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)
            Console.WriteLine();
            Console.WriteLine("--------方式三:回调方式,当异步线程结束,系统调用用户自定义的方法来处理结果(包括调用委托的EndInvoke方法)--------");
            CallBackStyle();
        }

       
    }
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 多线程 用委托实现异步_调用委托的BeginInvoke和EndInvoke方法 的相关文章

  • GO语言百分号参数

    常用 参数 v 值的默认格式 T 值得类型的GO语法表示 t 单词true或者false b 表示为二进制 c 该值对应的unicode码值 d 表示十进制 o 表示八进制 f 有小数部分但无指数部分 q 双引号输出
  • java第八节-重复执行

    import java util Scanner public class hello public static void main String args for System out println 34 hello 34 impor
  • java基础第九节-跳转控制语句-数组

    continue用在循环中 xff0c 基于条件控制 xff0c 跳过某次循环体内容的执行 xff0c 继续下一次的执行 break用在循环中 xff0c 基于条件控制 xff0c 终止循环体内容的执行 xff0c 结束当前的整个循环 数组
  • JAVA基础-基本类型转换

    int 和string的相互转换 1 int转换String public static String valuesOf int i 返回int参数的字符串表示形式 xff0c 该方法是String类的方法 1 String转换int pu
  • ubuntu系统-查看系统版本信息

    cat etc issue
  • Ubuntu查看cpu使用情况

    top命令查看cpu等信息 id是 xff1a 空闲 CPU 占用的 CPU 百分比
  • Ubuntu系统查看内存信息

    free命令查看内存信息 h 选项会在数字后面加上适于可读的单位 free h total xff1a 总物理内存大小 used xff1a 内存使用量 free xff1a 剩余可用内存
  • 嘉立创打样的阻抗匹配

    一 适用条件 最好使用4层板以上 xff0c 2层做匹配没啥意义 xff0c 套用大佬的话 主要是中间层和表层的距离近 xff0c 表层和中间层的玻璃纤维厚度是0 2mm xff0c 双层板最少是0 6mm xff0c 这里的差距很大 xf
  • echo 命令总结

    echo命令的功能是在显示器上显示一段文字 xff0c 一般起到一个提示的作用 此外 xff0c 也可以直接在文件中写入要写的内容 也可以用于脚本编程时显示某一个变量的值 xff0c 或者直接输出指定的字符串 echo命令的语法是 xff1
  • Android音频子系统(十三)------audio音频测试工具

    你好 xff01 这里是风筝的博客 xff0c 欢迎和我一起交流 测试音频延时的话 xff0c 一般使用WALT来测试是最为准确的 xff0c 他是借助了外部硬件来捕获音频信号 xff0c 某宝上有卖 xff1a 就是有丢丢小贵 xff0c
  • 一位北邮信通硕士的求职历程,看看 或许有帮助

    序 xff1a 写在前面的话 这篇文章的适用对象为 xff1a 非技术类方向的同学 xff0c 如果你是技术大牛 xff0c 你可以跳过这篇文章了 如果你觉得自己不喜欢技术或者技术不适合你 xff0c 此文或许会给你些有用的东西 简单介绍一
  • [转]STM32 串口传输处理方式 FreeRTOS+队列+DMA+IDLE (二)

    紧接着上一篇文章 xff0c 如何合理处理多个串口接收大量数据 此种方法 xff0c 很厉害 xff0c 很NB xff0c 首先 xff0c 利用DMA 可节省大量CUP资源 其次 xff0c 利用IDLE空闲中断来接收位置个数的数据 最
  • [转]FreeRTOS消息队列、信号量、事件标志组、任务通知

    功能及区别列表 消息队列 xff08 需要传递消息时使用 xff09 在任务与任务间 中断和任务间传递信息 xff0c 可以数据传输 事件标志组 xff08 多个事件同步 xff0c 不需要传递消息时使用 xff09 实现任务与任务间 中断
  • ubuntu 终端打不开解决办法

    由于ubuntu自带的是python3 5 在新安装了python3 6以后 xff0c 开机突然发现无论是点击图标还是使用快捷键终端都无法打开 xff0c 解决办法如下 xff1a xff11 xff0e 按Ctrl 43 Alt 43
  • Jack server already installed in "/***/.jack-server" 异常

    xff08 1 xff09 在新增新用户后 xff0c 进行android编译 xff0c 出现如下异常 xff1a Ensure Jack server is installed and started FAILED bin bash c
  • gstreamer移植qnx(二):交叉编译glib

    一 简介 这里以glib的2 63 0版本 xff0c QNX系统的版本是 xff1a 6 6 这里是为了编译gstreamer的依赖库 xff0c 也就是说最终目标 xff0c 是将gstreamer移植到QNX6 6系统上 我选择的是g
  • repo安装与简单使用

    一 概述 当一个大的项目需要拆分成很多的子项目 xff0c 或者说一个软件系统拆分成多个子系统 每一个子项目或者子系统都对应一个git repository 这种需求在实际项目当中是很常见的 xff0c 有的可能就直接写一个shell脚本来
  • 通过qemu-img命令将raw image转换成VMware虚拟硬盘vmdk

    为了在VMware中跑QNX系统 xff0c 我需要想办法将编译BSP生成的img文件固化到VMware的虚拟硬盘中去 xff0c 之前一直找不到方法 xff0c 到渐渐的只能用很笨的方法几次中专 将生成的img文件通过win32DiskI
  • WSL2 Ubuntu安装Qt(包括QtCreator)

    最近因为需要在Linux下使用qtcreator做一些界面开发的预研和学习 xff0c 主要是因为要交叉编译Qt 但又不想再使用虚拟机了 xff0c 真的太消耗内存了 于是就想着直接使用Windows10 下面的WSL2 怎么安装WSL2这
  • 架构师成长之路工具篇(1):markdown撰写文档

    今天笔者想说的工具就是markdown xff0c 正所谓工欲善其事必先利其器 xff0c 选择高效的工具自然能提升工作效率 笔者使用的markdown工具是 xff1a typora word太重 xff0c 太复杂 xff0c 在写文档

随机推荐

  • Artifact xxxx:Web exploded: Error during artifact deployment. See server log........

    从Git上拉取了一个新项目到idea xff0c 结果一运行就报错 xff0c 错误下图 看大家的解决方法基本都是重新部署Tomcat Maven或者项目 xff0c 还有什么jar包冲突要删除的 xff0c 齐齐试了一遍 xff0c 并没
  • 如何优雅的退出qemu虚拟环境

    在console环境下 xff0c 先 按 ctrl 43 a xff0c 释放之后再按 x 键 既可terminate qemu 注 xff1a 1 a 和 x 均为小写 2 必须先释放ctrl 43 a 之后 再按x键
  • xmake经验总结1:解决c++ future/promise抛出std::system_error的问题

    1 背景 1 1 场景 编译器 xff1a gcc 9 4 运行系统 xff1a Ubuntu 20 04 4 LTS xmake v2 6 7 场景 xff1a 其大致场景是使用c 43 43 的future promise功能 xff0
  • 神经网络实现手写数字识别(MNIST)

    一 缘起 原本想沿着 传统递归算法实现迷宫游戏 gt 遗传算法实现迷宫游戏 gt 神经网络实现迷宫游戏的思路 xff0c 在本篇当中也写如何使用神经网络实现迷宫的 xff0c 但是研究了一下 xff0c 感觉有些麻烦不太好弄 xff0c 所
  • 从高考到吃“软”饭

    上大学之前 xff0c 我是一个连本科和专科都分不清的农村小娃 那时的我天真的以为 xff0c 专科就是教授比较专业的知识 xff0c 而本科就是学得比较广而不深 上大学之后 xff0c 我算是开眼界了 xff0c 各种社团真是百花齐放 对
  • 解决visio对象在word中显示不全的问题

    作为一个软件工程师 xff0c 编写技术文档是常有的事情 xff0c 使用visio绘制各种图形 如 xff0c 流程图 xff0c 结构图 xff0c 框架图 xff0c 状态图等等 也是再正常不过的事情 如果我们在word中撰写文档时
  • git submodule使用以及注意事项

    一 背景 在平时的软件开发过程中常常会有这样的场景 xff0c 自己负责的某个模块会依赖其他模块或者第三方的library 这时你自己的模块是一个独立的代码仓库 xff0c 你想要实现这样一种功能 xff0c 当你从你的模块的代码仓库里把代
  • Webpack5 - 基本使用

    一 webpack有何作用 webpack是一个Javascript应用程序的模块打包器 它可以递归地构建一个应用程序的模块依赖关系图 xff0c 然后将所有模块打包在一起 为什么需要模块打包器 xff1a 现在的应用程序模块文件很多 xf
  • Vue.js - VueRouter的Hash与History模式 / 手写VueRouter

    一 Hash与History模式 Hash模式History模式url地址外观http localhost 8081 abouthttp localhost 8080 about原理基于锚点 xff0c 监听锚点变化时触发的onhashch
  • Vue.js - Vue.js响应式原理(1/2)

    一 数据驱动 数据响应式 xff1a 数据改变 xff0c 则视图改变 xff0c 避免频繁的Dom操作 xff0c 提高运行效率 双向绑定 xff1a 数据改变 xff0c 则视图改变 xff1b 视图改变 xff0c 则数据也随之改变
  • Vue.js - 模拟Vue.js响应式原理(2/2)

    项目仓库 xff1a https gitee com big right right vue responsive tree master L8 一 类的说明 Vue类 xff1a 保存传入的选项数据 xff0c 把选项data中的成员注入
  • OpenFlow Switch Specification 1.3.0 (三)

    六 OpenFlow 安全通道 xff08 OpenFlow Channel xff09 OpenFlow 通道是连接每一个交换到控制器的接口 通过这个接口 xff0c 控制器配置和管理交换机 xff0c 从交换机接收事件 xff0c 向交
  • MATLAB并行加速方法

    用MATLAB运行计算任务时 xff0c 有时会遇到程序中有很多重复计算部分 xff0c 多次循环中 xff0c 每一次的计算之间无相互依赖 xff08 即后一次的计算不需要使用到前一次的计算结果 xff09 xff0c 可能仅改变了输入参
  • 一名本科毕业女程序员的2013总结

    姓名 xff1a XXX 性别 xff1a 女 学历 xff1a 大学本科 毕业时间 xff1a 2013 06 31 参加工作 xff1a 2013 07 03 单位 xff1a 北京 某国企下属单位 职位 xff1a 程序员 1 初始
  • .NET用NCO连接SAP RFC---写数据到SAP

    1 环境 xff1a a win7 43 64位操作系统 b VS2012 c nco3 0 xff08 64bit 下载网址 xff1a http www dllbang com dll sapnco dll xff09 xff0c d
  • .NET Framwork,C#入门开发教程,零基础必看

    初识 NET Framwork和开发过程 一 什么是 NET Framework NETFramework是一个开发平台 xff0c 可以在其上使用多种语言开发程序 xff1a 如C xff0c VB xff0c C 43 43 xff08
  • 如何清除IIS缓存

    问题描述 xff1a 在IIS的默认网站下创建了一个虚拟目录名A xff0c 然后删除这个虚拟目录 后来需要重新创建一个同名虚拟目录 xff0c 映射的还是原来的项目文件 xff0c 只是项目文件的物理路径发生了变化 xff0c 这个新虚拟
  • jqGrid 多选复选框 编辑列

    1 首先看一下效果 2 html代码 lt table id 61 34 grid table 34 gt lt table gt 3 在 function 方法中 xff0c 写如下方法 xff0c 用json数据填充jqGrid xff
  • Asp.net WebApi 项目示例(增删改查)

    1 WebApi是什么 ASP NET Web API 是一种框架 xff0c 用于轻松构建可以由多种客户端 xff08 包括浏览器和移动设备 xff09 访问的 HTTP 服务 ASP NET Web API 是一种用于在 NET Fra
  • C# 多线程 用委托实现异步_调用委托的BeginInvoke和EndInvoke方法

    1 C 中的每一个委托都内置了BeginInvoke和EndInvoke方法 xff0c 如果委托的方法列表里只有一个方法 xff0c 那么这个方法就可以异步执行 xff08 不在当前线程里执行 xff0c 另开辟一个线程执行 xff09