C#异步有多少种实现方式?

这篇具有很好参考价值的文章主要介绍了C#异步有多少种实现方式?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

  微信群里的一个提问引发的这个问题,有同学问:C#异步有多少种实现方式?想要知道C#异步有多少种实现方式,首先我们要知道.NET提供的执行异步操作的三种模式,然后再去了解C#异步实现的方式。

.NET异步编程模式

.NET 提供了执行异步操作的三种模式:

  • 基于任务的异步模式 (TAP) ,该模式使用单一方法表示异步操作的开始和完成。 TAP 是在 .NET Framework 4 中引入的。 这是在 .NET 中进行异步编程的推荐方法。 C# 中的 async 和 await 关键词以及 Visual Basic 中的 Async 和 Await 运算符为 TAP 添加了语言支持。 有关详细信息,请参阅基于任务的异步模式 (TAP)。

  • 基于事件的异步模式 (EAP),是提供异步行为的基于事件的旧模型。 这种模式需要后缀为 Async 的方法,以及一个或多个事件、事件处理程序委托类型和 EventArg 派生类型。 EAP 是在 .NET Framework 2.0 中引入的。 建议新开发中不再使用这种模式。 有关详细信息,请参阅基于事件的异步模式 (EAP)。

  • 异步编程模型 (APM) 模式(也称为 IAsyncResult 模式),这是使用 IAsyncResult 接口提供异步行为的旧模型。 在这种模式下,同步操作需要 Begin 和 End 方法(例如,BeginWrite 和 EndWrite以实现异步写入操作)。 不建议新的开发使用此模式。 有关详细信息,请参阅异步编程模型 (APM)。

C#异步四种实现方式

1、异步方法(Async Method TAP模式)

使用async/await关键字实现异步编程,这是比较常用的一种异步实现方式。例如:

    public async Task TestDoSomeAsync()
    {
        await Task.Delay(1000*10);
        Console.WriteLine("Async method completed.");
    }

2、任务并行库(TPL, Task Parallel Library TAP模式)

通过 Task 和 Task<T> 类型实现异步编程,可以利用多核处理器,并发执行多个独立的任务。例如:

        public static void TestTaskParallel()
        {
            var task1 = Task.Run(() =>
            {
                Console.WriteLine("Task 1 completed.");
            });

            var task2 = Task.Run(() =>
            {
                Console.WriteLine("Task 2 completed.");
            });

            Task<int> task3 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Task 3 completed.");
                return 20;// 返回一个整数值
            });

            //等待所有任务完成
            Task.WaitAll(task1, task2, task3);
        }

3、Asynchronous Programming Model(APM模式)

是一种经典的异步编程模式,需要手动创建回调函数,用于处理完成或错误的通知。可以通过 IAsyncResult 设计模式的 Begin 和 End 方法来实现,其中 Begin 方法开始异步操作,而 End 方法在异步操作完成时执行,并返回异步操作的结果。

需要注意的是,APM 模式通过 IAsyncResult 接口来存储异步操作的状态和结果,相对比较复杂,代码量也较大。同时,在使用 APM 模式时,还需要手动处理回调函数和等待异步操作完成等细节工作,使得开发起来相对较为繁琐。

    class Program
    {
        static void Main(string[] args)
        {
            // 创建异步操作类实例
            MyAsyncClass asyncClass = new MyAsyncClass();

            // 开始异步操作
            IAsyncResult result = asyncClass.BeginDoWork(null, null);

            // 主线程执行其他操作
            // 等待异步操作完成并获取结果
            int res = asyncClass.EndDoWork(result);

            // 处理异步操作的结果
            Console.WriteLine("Result: " + res);

            Console.ReadLine();
        }
    }

    class MyAsyncClass
    {
        /// <summary>
        /// 异步执行的方法
        /// </summary>
        /// <param name="callback">callback</param>
        /// <param name="state">state</param>
        /// <returns></returns>
        public IAsyncResult BeginDoWork(AsyncCallback callback, object state)
        {
            // 创建一个新的异步操作对象
            MyAsyncResult result = new MyAsyncResult(state);

            // 开始异步操作
            Thread thread = new Thread(() =>
            {
                try
                {
                    // 执行一些操作
                    int res = 1 + 2;

                    // 设置异步操作的结果
                    result.Result = res;

                    // 触发回调函数
                    callback?.Invoke(result);
                }
                catch (Exception ex)
                {
                    // 设置异步操作的异常
                    result.Error = ex;

                    // 触发回调函数
                    callback?.Invoke(result);
                }

            });
            thread.Start();

            // 返回异步操作对象
            return result;
        }

        /// <summary>
        /// 结束异步执行的方法
        /// </summary>
        /// <param name="result">result</param>
        /// <returns></returns>
        public int EndDoWork(IAsyncResult result)
        {
            // 将 IAsyncResult 转换为 MyAsyncResult 类型,并等待异步操作完成
            MyAsyncResult myResult = (MyAsyncResult)result;
            myResult.AsyncWaitHandle.WaitOne();

            // 在异步操作中抛出异常
            if (myResult.Error != null)
            {
                throw myResult.Error;
            }

            // 返回异步操作的结果
            return myResult.Result;
        }
    }

    class MyAsyncResult : IAsyncResult
    {
        public bool IsCompleted => AsyncWaitHandle.WaitOne(0);
        public WaitHandle AsyncWaitHandle { get; } = new ManualResetEvent(false);
        public object AsyncState { get; }
        public bool CompletedSynchronously => false;

        public int Result { get; set; }

        /// <summary>
        /// 存储异步操作的结果或异常信息
        /// </summary>
        public Exception Error { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="asyncState">asyncState</param>
        public MyAsyncResult(object asyncState)
        {
            AsyncState = asyncState;
        }
    }

4、Event-based Asynchronous Pattern(EAP模式)

一种已过时的异步编程模式,需要使用事件来实现异步编程。例如:

需要注意的是,EAP 模式通过事件来实现异步编程,相对于 APM 模式更加简洁易懂,同时也避免了手动处理回调函数等细节工作。但是,EAP 模式并不支持 async/await 异步关键字,因此在一些特定的场景下可能不够灵活。

public class MyAsyncClass : Component
    {
        /// <summary>
        /// 声明一个委托类型,用于定义异步操作的方法签名
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public delegate int MyAsyncDelegate(int arg);

        /// <summary>
        /// 声明一个事件,用于通知异步操作的完成
        /// </summary>
        public event MyAsyncDelegate OperationNameCompleted;

        /// <summary>
        /// 异步执行方法,接受一个参数 arg
        /// </summary>
        /// <param name="arg"></param>
        public void DoWorkAsync(int arg)
        {
            // 将异步操作放入线程池中执行
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), arg);
        }

        /// <summary>
        /// 真正的异步操作
        /// </summary>
        /// <param name="obj"></param>
        private void DoWork(object obj)
        {
            int arg = (int)obj;
            int res = arg + 1;

            // 触发事件,传递异步操作的结果
            OperationNameCompleted?.Invoke(res);
        }
    }

参考文章

https://learn.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/

 文章来源地址https://www.toymoban.com/news/detail-436895.html

 

到了这里,关于C#异步有多少种实现方式?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 企业微信群:机器人实现定时提醒功能

    如果每天都需要,或者经常需要提醒企业微信群里面的人做某一件事情的话,靠人力去实现比较费力,而且偶尔忘记。 正好,企业微信群有一个机器人,正可以实现这一功能。 1、首先,在企业微信群,添加一个机器人。 2、根据企业微信机器人的配置说明,编写程序。这里

    2024年02月16日
    浏览(147)
  • 运用python实现企业微信群机器人消息推送

    使用场景 :将BI报表精准推送入(群),精准触达用户 目的 :提高管理层对数据的感知度 工具:python+企业微信 步骤: 1、创建企业微信群机器人,提取Webhook地址(群机器人地址) 2、编写代码填充推送内容信息实现推送 3、其他需求自定义代码编写 实现方法1–优化后 实现

    2024年02月16日
    浏览(36)
  • Python实现企业微信群机器人自动化推送

    人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 ——《百度百科》 实际工作中,有类似这样的场景, 需要将某些通知信息定期发送到企业微信群,需要将公司某些指标的异

    2024年02月09日
    浏览(61)
  • 微信小程序开发一个多少钱

    小程序开发是当前比较流行的一项技术服务,能够为企业和个人带来巨大的商业价值和社会价值,但是小程序开发费用也是潜在的成本之一。在选择小程序开发服务时,了解开发费用如何计算、影响价格的因素以及如何降低成本等方面的知识,可以帮助您更好地做出决策。

    2024年02月02日
    浏览(67)
  • Java生成微信小程序二维码,5种实现方式,一个比一个简单

    先介绍一下 项目场景 ,主要是通过微信小程序二维码 裂变分享 ,每个账号有专属邀请二维码,分享出去,有新人扫码入驻,就可以得到现金奖励或红包奖励。当然,产品设计会更丰富,不止有裂变模式,还有渠道推广模式,还有各种奖励规则,但核心实现都是生成二维码。

    2024年02月03日
    浏览(53)
  • 微信小程序怎么制作?制作一个微信小程序需要多少钱?

    随着移动互联网的快速发展,微信小程序已成为连接用户与服务的重要桥梁。它以其便捷性和易用性,为各类企业和个人提供了一个全新的展示和交易平台。那么,如何制作一个微信小程序?又需要投入多少资金呢?本文将为您提供全面的解答。 制作微信小程序的步骤 1 、准

    2024年04月10日
    浏览(52)
  • 在微信小程序中跳转到另一个小程序(多种实现方式)

    今天在项目中刚好遇到一个到从当前小程序中跳转到另一个小程序,下面分享一下我总结的几个比较简单的跳转方式吧。 如果不给path属性是默认跳到目标小程序首页,如果想跳到其他页面就要配置path属性,这样就能实现从当前微信小程序跳转到另外一个小程序啦~ 也有办法

    2024年02月11日
    浏览(47)
  • HTML5+CSS3模拟实现《亮剑》平安县城一役精彩微信群聊-谁开的炮?

    转眼从2005年到现在,《亮剑》已经播出多年,但热度依然不减,而且每次重温我都会看出不一样的意蕴,今天,我就用 HTML5+CSS3 模拟实现《亮剑》平安县城一役精彩 微信群聊 -谁开的炮? 目录 1. 实现思路 2. 素材介绍 3. 微信群聊顶部 + 底部 + 聊天区域实现 4. 聊天区域的实现

    2024年02月02日
    浏览(42)
  • 如何建立自己的微信小程序,做一个微信小程序大概多少钱?

    如今,小程序的功能越来越强大,也越来越受欢迎,它不仅能帮助企业和商家做推广,还能给他们带来很多好处。所以,很多企业都开始建立自己的小程序。但是对于如何建立自己的微信小程序,以及做一个微信小程序大概多少钱,很多人并不是很清楚。下面我们就来了解一

    2024年02月11日
    浏览(54)
  • 【微信小程序】实现点击+号弹出一个附着旁边的弹窗进行多个方式的选择

    在微信小程序中,你可以使用小程序的组件和事件来实现点击+号弹出一个附着在+号旁边的弹窗,以进行多个方式的选择。以下是一个示例代码: 在wxml文件中,创建一个按钮,并为按钮绑定一个点击事件: 在上述代码中,我们创建了一个按钮,用于展示+号图标,并给按钮绑

    2024年02月14日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包