首页 > 编程语言 >C# BeginInvoke实现异步编程

C# BeginInvoke实现异步编程

时间:2023-09-27 10:13:16浏览次数:34  
标签:异步 C# System int 线程 BeginInvoke using

C# BeginInvoke实现异步编程-CSDN博客

https://blog.csdn.net/Nire_Yeyu/article/details/133203267

 

C# BeginInvoke实现异步编程
BeginInvoke实现异步编程的三种模式:

1.等待模式
在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等异步方法完成之后再继续;
eg:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BeginInvokeDemo
{
public delegate int myDelegate(int num1,int num2); //声明委托
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private int Cal_Task1(int num1, int num2) //方法一
{
Thread.Sleep(3000); //进程延时3S,延长执行时间
return num1 + num2;
}
private int Cal_Task2(int num1, int num2) //方法二
{
return num1 + num2;
}
private void button_Calculate_Click(object sender, EventArgs e)
{
myDelegate objTest = new myDelegate(Cal_Task1); //定义委托变量,引用任务1
IAsyncResult iar = objTest.BeginInvoke(3,4,null,null); //异步调用
textBox_Result1.Text = "计算中...";

textBox_Result2.Text = Cal_Task2(5,6).ToString(); //同时可以并行其他任务

int result = objTest.EndInvoke(iar); //获取异步执行结果
//委托类型的EndInvoke()方法:借助IAsyncResult接口对象,不断查询异步调用是否结束。
//该方法知道被异步调用的方法所有的参数,所以,异步调用结束后,取出异步调用结果作为返回值
textBox_Result1.Text = result.ToString();
}
}
}

 

2.轮询模式
原始线程定期检查发起的线程是否完成,如果没有则可以继续做一些其他事情;
eg:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
delegate int MyDel(int num1,int num2);
class Program
{
static void Main(string[] args)
{
MyDel del = new MyDel(Sum);
IAsyncResult iar = del.BeginInvoke(3,4,null,null);
Console.WriteLine("After BeginInvoke");

while(!iar.IsCompleted)
{
Console.WriteLine("Not Done");

//继续处理
for (long i = 0; i < 10000000; i++)
; //空语句
}
Console.WriteLine("Done");

int result = del.EndInvoke(iar);
Console.WriteLine("Result:{0}",result);

Console.ReadLine();
}

static int Sum(int x,int y)
{
Console.WriteLine(" Inside Sum");
Thread.Sleep(100);

return x + y;
}
}
}

 

3.回调模式
原始线程一直执行,无需等待或检查发起的线程是否完成。在发起的线程中引用方法完成之后,发起的线程就会调用回调方法,由回调方法再调用EndInvoke之前处理异步方法的结果。
eg:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace _02_AsyncCallBackDemo
{
public partial class FrmCalllBack : Form
{
public FrmCalllBack()
{
InitializeComponent();

//【3】初始化委托变量
this.objMyCal = new MyCalculator(ExecuteTask);

//也可以直接使用Lambda表达式
//this.objMyCal = (num, ms) =>
//{
// System.Threading.Thread.Sleep(ms);
// return num * num;
//};
}

//【3】创建委托变量(因为异步函数和回调函数都要用,所以定义成成员变量)
private MyCalculator objMyCal = null;

//【4】同时执行多个任务
private void btnExec_Click(object sender, EventArgs e)
{
//发布任务
for (int i = 1; i < 11; i++)
{
//开始异步执行
objMyCal.BeginInvoke(10 * i, 1000 * i, MyCallBack, i);
//最后一个参数i给回调函数的字段AsyncState赋值,如果数据很多可以定义成类或结构
}
}

//【5】回调函数
private void MyCallBack(IAsyncResult result)
{
int res = objMyCal.EndInvoke(result);
//显示异步调用结果:result.AsyncState字段用来封装回调函数自定义参数,object类型
Console.WriteLine("第{0}个计算结果为:{1}", result.AsyncState.ToString(), res);
}

//【2】根据委托定义一个方法:返回一个数的平方
private int ExecuteTask(int num, int ms)
{
System.Threading.Thread.Sleep(ms);
return num * num;
}

//【1】声明委托
private delegate int MyCalculator(int num, int ms);
}
//异步编程的总结:
//1. 异步编程是建立在委托的基础上一种编程的方法。
//2. 异步调用的每个方法都是在独立的线程中执行的。因此,本质上就是一种多线程程序,是简化的多线程。
//3. 比较适合在后台运行较为耗时的《简单任务》,并且任务之间要求相互独立,任务中不应该有直接访问可视化控件大代码。
//4. 如果后台任务要求必须按照特定顺序执行,或者访问共享资源,则异步编程不太适合,应选择多线程开发技术。
}

 

————————————————
版权声明:本文为CSDN博主「Danny_hi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43024228/article/details/98600254

标签:异步,C#,System,int,线程,BeginInvoke,using
From: https://www.cnblogs.com/zkwarrior/p/17732007.html

相关文章

  • 【RocketMQ】主从同步实现原理
    RocketMQ支持集群部署来保证高可用。它基于主从模式,将节点分为Master、Slave两个角色,集群中可以有多个Master节点,一个Master节点可以有多个Slave节点。Master节点负责接收生产者发送的写入请求,将消息写入CommitLog文件,Slave节点会与Master节点建立连接,从Master节点同步消息数据。......
  • C# 枚举使用[Flags] 特性形成一个位掩码及判断是否存在某个枚举组合
    在C#中,通过给枚举类型添加 [Flags] 特性,可以指示该枚举类型是用于表示位标志的枚举。使用带有 [Flags] 特性的枚举类型允许将多个枚举值组合在一起,形成一个位掩码,提供了一种更方便和可读性更好的方式来表示多个选项的组合。当给枚举类型添加 [Flags] 特性后,可以使用按位或......
  • macOS Sonoma 14 (23A344) 正式版发布,ISO、IPSW、PKG 下载
    macOSSonoma今日推出,全面提升生产力和创意工作流macOSSonoma14(23A344)正式版发布,ISO、IPSW、PKG下载2023年9月26日(北京时间27日凌晨)macOSSonoma正式版现已发布。本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,......
  • macOS Sonoma 14 (23A344) 正式版 Boot ISO 原版可引导镜像下载
    macOSSonoma14(23A344)正式版BootISO原版可引导镜像下载2023年9月26日(北京时间27日凌晨)macOSSonoma正式版现已发布。本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows......
  • 进入BIOS推荐方法ThinkPad , ThinkCentre , ThinkStation
    描述用户可以轻松地调整计算机时间,日期,查看硬件配置信息(机器类型,序列号,内存和HDD等),设置无线或热键功能以及在BIOS下调整开机启动过程。推荐的进入BIOS方法如下所示。通过功能键(Fn)进入BIOS从Windows10进入BIOS从Windows8.1/8进入BIOS观看我们的视频:[视频]什么是BIOS?[视频]如......
  • 视频监控/监控汇聚平台EasyCVR助力档案库房可视化管理的应用方案
    档案作为一种特殊的留存记录,具有珍贵的历史价值和文化遗产意义。它是人类活动真实的见证,记录了辉煌时刻和普通人的生活轨迹,对社会发展和经济建设起着举足轻重的作用。如今随着市场经济的不断发展和人类文明的飞速推进,档案的价值更加凸显,档案的储存和管理也备受关注。提升档案数字......
  • UCLASS是一种类说明符吗?
    我们知道,在java里有一个东西叫注解。注解的使用在spring框架里更是被用的出神入化。那么C++里呢?有没有对类进行说明的类型 第一种类说明符:Abstract。抽象类说明符将类声明为“抽象基类”,防止用户在虚幻编辑器中向世界添加此类的参与者,或在游戏中创建此类的实例。 第二种......
  • vscode编写markdown
    1.需求分析2.环境搭建1.需求分析最近在网上折腾了好久Markdown的写作环境,作为一个普通用户,总结一下个人对于Markdown写作环境的几点需求。由于本人刚接触Markdown不久,因此,需求也比较简单,想看具体搭建步骤的可以直接跳到第二章环境搭建:本地存储。这一点主要是出于隐私要......
  • 视频融合平台EasyCVR接入华为ivs3800平台提示400报错的原因及解决方法
    青犀视频平台的开源EasyDarwin视频监控解决方案EasyCVR在复杂网络环境中表现出色。它能够将分散的各类视频资源集中管理,实现统一汇聚和整合。EasyCVR支持多种画面窗口播放模式,包括1、4、9、16个画面窗口,同时可以播放多路视频流,并且支持视频定时轮播功能。此外,EasyCVR还兼容多种播......
  • How to get the original size of an image using JavaScript All In One
    HowtogettheoriginalsizeofanimageusingJavaScriptAllInOne如何使用JavaScript获取一个图片像的原始大小naturalWidth&naturalHeightletoutput=document.querySelector(".output");letimage=document.querySelector("img");window.add......