当前位置: 首页 > news >正文

C#异步委托的三种实现 BeginInvoke / EndInvoke / IsCompleted

  • 本文将介绍C#异步委托的三种实现方式,并给出相关示例代码及解析。

注意事项

    1. 用委托开启线程的前提是:创建项目时必须选择“.NET Framework",如果选择的是”.Net Core“,在调用BeginInvoke时,系统会报错”Operation is not supported on this platform.“。
    1. 异步调用的另一个前提是:委托的方法列表中只能包含一个方法。

等待至完成

  • 通过BeginInvoke和EndInvoke实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace FrameworkDemo
{public delegate long MyDel(int a, int b);class Program{static long sum(int a, int b) {Thread.Sleep(10 * 1000);return a + b;}static void Main(string[] args){// 异步委托操作描述IAsyncResult res = null;long result = 0;AsyncCallback callback = ar =>{// 输出结果:“计算结果为:11”Console.WriteLine($"{ar.AsyncState}{result}");};MyDel del = new MyDel(sum);// BeginInvoke开启异步调用// res的打印结果为System.Runtime.Remoting.Messaging.AsyncResultres = del.BeginInvoke(3, 8, callback, "计算结果为");  // 等待线程结束,并获取返回值result = del.EndInvoke(res);Console.ReadLine();}}
}
  • BeginInvoke函数的最后两个参数分别是一个回调函数,以及传入这个回调函数的参数。当委托线程运行结束后,会自动运行这个回调函数。之前的参数个数及类型取决于定义委托时参数的类型和个数。
  • IAsyncResult类型表示对异步委托操作的描述,一调用异步委托,就立刻会在主函数中得到这个返回值,打印结果为“System.Runtime.Remoting.Messaging.AsyncResult”。
  • EndInvoke会把主线程卡主,知道异步委托方法结束,此时将之前拿到的异步委托操作描述作为参数传入,即可获得异步委托函数的真正返回值。

轮询模式

  • 通过IsCompleted实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace FrameworkDemo
{public delegate long MyDel(int a, int b);class Program{static long sum(int a, int b) {Thread.Sleep(10 * 1000);return a + b;}static void Main(string[] args){// 异步委托操作描述IAsyncResult res = null;long result = 0;AsyncCallback callback = ar =>{// 输出结果:“计算结果为:11”Console.WriteLine($"{ar.AsyncState}{result}");};MyDel del = new MyDel(sum);// BeginInvoke开启异步调用// res的打印结果为System.Runtime.Remoting.Messaging.AsyncResultres = del.BeginInvoke(3, 8, callback, "计算结果为");while (!res.IsCompleted) {/*一系列想要的操作*/}// 等待线程结束,并获取返回值result = del.EndInvoke(res);Console.ReadLine();}}
}
  • 之前我们调用BeginInvoke后,直接调用EndInvoke,这使得主线程一直卡主,直到委托线程返回,通过IsComplated进行轮询线程状态,我们可以在循环中利用等待时间,执行一些别的想要的工作。

回调

  • 关于回调函数,比较标准的写法如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace FrameworkDemo
{public delegate long MyDel(int a, int b);class Program{static long sum(int a, int b) {Thread.Sleep(10 * 1000);return a + b;}// 异步委托执行完成后需要调用的回调函数static void testCallback(IAsyncResult ar) {System.Runtime.Remoting.Messaging.AsyncResult varResult =(System.Runtime.Remoting.Messaging.AsyncResult)ar;MyDel test = (MyDel)varResult.AsyncDelegate;long result = test.EndInvoke(ar);Console.WriteLine($"{ar.AsyncState}: {result}");}static void Main(string[] args){           MyDel del = new MyDel(sum);AsyncCallback asyncTest = new AsyncCallback(testCallback);del.BeginInvoke(3, 8, asyncTest, "计算结果为");Console.ReadLine();}}
}
  • 当异步委托运行结束后,系统会自动调用回调函数,并将异步委托描述信息IAsyncResult作为参数传入回到函数中,因此我们需要做的就是解析异步委托描述信息。
http://www.lryc.cn/news/177701.html

相关文章:

  • 在HTTP请求中安全传输base64编码的字符串
  • 05预测识别-依托YOLO V8进行训练模型的识别——对视频中的图片进行识别
  • LeetCode算法题---第3天
  • 欧洲FBA专线海运与陆运的差别
  • UDS诊断
  • 计算材料学学习记录1
  • PHP8中的构造方法和析构方法-PHP8知识详解
  • 【GPU编程】Visual Studio创建基于GPU编程的项目
  • MySQL面试题-索引的基本原理及相关面试题
  • MySQL学习笔记19
  • 为什么u盘在mac上显示不出来
  • 【golang】调度系列之sysmon
  • 货物寄到英国选择什么物流比较划算?
  • vite + react 基本项目搭建
  • 一个方法解决三道区间问题
  • sub0 里斯本精彩回顾:探索波卡区块的创新空间
  • 颜色+情感的英语表达还有这些,零基础学英语口语去哪里,柯桥有推荐的吗?
  • exoplayer的使用-6,播放器的选择
  • Windows上安装 Go 环境
  • 【设计模式】四、工厂模式
  • 十九,镜面IBL--BRDF积分贴图
  • Linux 创建 终止线程(thread)
  • 【IPC 通信】信号处理接口 Signal API(6)
  • ipaguard界面概览
  • 萌新的FPGA学习绪论-1
  • 目标检测算法改进系列之Backbone替换为EMO
  • Laravel一些优雅的写法
  • vue+three.js中使用Ammo.js
  • 【k8s】kubectl命令详解
  • Centos 7 部署SVN服务器