C# BeginInvoke实现异步编程方式

 更新时间:2023年01月24日 14:32:37   作者:Danny_hi  
这篇文章主要介绍了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. 如果后台任务要求必须按照特定顺序执行,或者访问共享资源,则异步编程不太适合,应选择多线程开发技术。
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • winform中的ListBox和ComboBox绑定数据用法实例

    winform中的ListBox和ComboBox绑定数据用法实例

    这篇文章主要介绍了winform中的ListBox和ComboBox绑定数据用法,实例分析了将集合数据绑定到ListBox和ComboBox控件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2014-12-12
  • C#递归实现回文判断算法

    C#递归实现回文判断算法

    这篇文章主要介绍了C#递归实现回文判断算法,方法简单实用,需要的朋友可以参考下
    2014-10-10
  • C# CSV文件读写的实现

    C# CSV文件读写的实现

    本文主要介绍了C# CSV文件读写的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • c#数据库与TXT导入导出的实例

    c#数据库与TXT导入导出的实例

    最近刚学完ADO.NET,做了个数据导入导出的题目,是将txt中的数据导入数据库,然后将数据库中的数据导出到txt中,这里说的数据的格式是“tom|23”,tom指名字,23指年龄。废话也不多说了,大家直接看代码。
    2013-04-04
  • c# 实现语音聊天的实战示例

    c# 实现语音聊天的实战示例

    这篇文章主要介绍了c# 实现语音聊天的实战示例,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-02-02
  • C#并行库Parallel类介绍

    C#并行库Parallel类介绍

    这篇文章介绍了C#并行库Parallel类,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#表达式树讲解

    C#表达式树讲解

    本文详细讲解了C#表达式树的创建、生成和使用,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • WPF模拟实现Gitee泡泡菜单的示例代码

    WPF模拟实现Gitee泡泡菜单的示例代码

    这篇文章主要介绍了如何利用WPF模拟实现Gitee泡泡菜单,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2022-08-08
  • C#实现提取Word中插入的多媒体文件(视频,音频)

    C#实现提取Word中插入的多媒体文件(视频,音频)

    在Word中可将文件通过OLE对象嵌入的方式插入到文档,包括Word、excel、PDF、PPT、图片、宏文件、文件包等在内的多种文件类型。本文将利用C#实现提取插入在Word文件中的这些多媒体文件,感兴趣的可以了解一下
    2022-02-02
  • 为何Linq的Distinct实在是不给力

    为何Linq的Distinct实在是不给力

    本篇文章对Linq的Distinct进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论