多线程操作之异步委托

C#异步委托的三种实现 BeginInvoke / EndInvoke / IsCompleted C#异步委托的三种实现 BeginInvoke / EndInvoke / IsCompleted。 阅读详情

在应届生找工作的时候,多线程操作几乎是所有的公司都会问及的一个基本问题。

 

这里做了一个多线程操作的总结,这里总结了通过异步委托来实现多线程操作。

 

定义一个委托,是创建一个线程的最简单的方法,并且异步调用它。委托是方法的类型安全的引用。同时委托还智齿异步调用方法。

委托使用线程池来完成异步任务。

当自己的程序使用异步委托的时候,委托会自动创建ige执行线程的任务。委托使用线程池完成异步任务,所有的异步委托调用,都会通过调用系统线程池中的线程来完成调用异步任务。

 

 

在下面的简单例子中,我们定义了一个异步委托,并在每次输出的时候显示该函数运行在哪个线程中。

 

在异步委托中,可以使用三种技术来异步的调用委托。下面分别介绍三种调用异步委托的方法。

 

1. 投票判断异步委托是否完成

 

在委托中调用BeginInvoke()方法,返回IAsyncResult结果。程序的源代码如下:

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

namespace AsyncDelegate
{
    class Program
    {
        public delegate int TakeSomeTimeDelegate(int data,int ms);

        static void Main(string[] args)
        {
            TakeSomeTimeDelegate dl=TakeSomeTime;
            IAsyncResult ar=dl.BeginInvoke(1,200,null,null);

            while (!ar.IsCompleted)
            {
                Console.WriteLine(".");
                Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(50);
            }

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

        static int TakeSomeTime(int data, int ms)
        {
            Console.WriteLine("TakeSomeTime started!");
            Console.WriteLine("Run in thread:"+Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(ms);
            Console.WriteLine("TakeSomeTime Completed!");
            return ++data;
        }
    }
}


 

该程序的输出结果如图:

可以看到主线程和异步委托线程是同时执行的。

如果在委托结束之前不等待委托完成其他任务就结束主线程,委托线程就会停止。

int result = dl.EndInvoke(ar); 这里的EndInvoke()函数会一直等在异步委托完成并在异步委托完成之前阻断主线程。这样就可以通过这个函数保证异步委托能够正确完成。

 

2. 等待句柄判断异步委托完成

通过AsyncWatiHandle属性,访问等待句柄。WaitOne()方法阻断当前线程,直到异步调用线程完成返回可以利用的句柄以后再执行当前线程。

程序:

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

namespace AsyncDelegate
{
    class Program
    {
        public delegate int TakeSomeTimeDelegate(int data,int ms);

        static void Main(string[] args)
        {
            TakeSomeTimeDelegate dl=TakeSomeTime;
            IAsyncResult ar=dl.BeginInvoke(1,200,null,null);

            while (true)
            {
                Console.WriteLine(".");
                Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);
                if (ar.AsyncWaitHandle.WaitOne(100, false))
                {
                    Console.WriteLine("Can get the result now");
                    break;
                }
            }

            //while (!ar.IsCompleted)
            //{
            //    Console.WriteLine(".");
            //    Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);
            //    Thread.Sleep(50);
            //}

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

        static int TakeSomeTime(int data, int ms)
        {
            Console.WriteLine("TakeSomeTime started!");
            Console.WriteLine("Run in thread:"+Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(ms);
            Console.WriteLine("TakeSomeTime Completed!");
            return ++data;
        }
    }
}


运行结果:

 

 

ar.AsyncWaitHandle.WaitOne()阻断了当前线程, 直到异步调用线程完成获得可以利用的句柄以后再次执行当前线程。

 

3. 利用异步回调函数判断异步调用线程是否结束

 

回调函数的操作比较复杂, 而且对于程序的理解和维护造成非常大的困难。所以一般情况下能不用回调函数就不要使用回调函数。

 

使用回调函数,必须注意这个函数从委托线程中调用,而不是从主线程中调用回调函数。

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

namespace AsyncDelegate
{
    class Program
    {
        public delegate int TakeSomeTimeDelegate(int data,int ms);

        static void Main(string[] args)
        {
            TakeSomeTimeDelegate dl=TakeSomeTime;
            IAsyncResult ar = dl.BeginInvoke(1, 200, TakeSomeTimeCompleted, dl);
            for (int i = 0; i < 10;i++ )
            {
                Console.WriteLine(".");
                Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(50);
            }

            //int result = dl.EndInvoke(ar);
            //Console.WriteLine("Result:{0}", result);
        }

        static int TakeSomeTime(int data, int ms)
        {
            Console.WriteLine("TakeSomeTime started!");
            Console.WriteLine("Run in thread:"+Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(ms);
            Console.WriteLine("TakeSomeTime Completed!");
            return ++data;
        }

        static void TakeSomeTimeCompleted(IAsyncResult ar)
        {
            if (ar==null)
            {
                throw new ArgumentNullException("ar");
            }
            TakeSomeTimeDelegate dl = ar.AsyncState as TakeSomeTimeDelegate;
            int result = dl.EndInvoke(ar);
            Console.WriteLine("result : {0}", result);
            //Console.WriteLine("Run in thread:" + Thread.CurrentThread.ManagedThreadId);
        }
    }
}


 

运行结果:

 

 

C#-异步委托 C# 异步委托也是属于异步编程中的一种,可以称为 Asynchronous Programming(异步编程)或者 Asynchronous Programming Model(异步编程模型),因为这是实现异步编程的模式。委托是 C#1.0 就有的特性,并且 .NET v1.0 同时也伴随有 AsyncCallback、IAsyncResult 等类/接口的出现,所以所有的 .NET 版本中都是支持的。 阅读详情

相关推荐

GD32 ARM单片机开发规范检查清单 GD32嵌入式C代码检查清单

以下检查清单基于您的编程规范制定,可用于代码审查和自检过程。通过逐项检查,确保代码符合项目规范要求。fill:#333;color:#333;color:#333;fill:none;代码审查流程基础规范检查功能实现检查性能与安全检查文档与注释检查命名规范格式规范结构规范功能完整性API设计错误处理资源使用安全措施性能优化代码注释文档完整性。

weesky 1207

C# 多线程 异步委托BeginInvoke

异步委托解决了线程池不能返回值的问题,允许双向传递参数,同时可以在调用线程上抛出委托方法中未处理的异常。注:EndInvoke是必须的。相互学习,共同富裕。

吴启林的博客 1462

HarmonyOS实战开发 —— 基于Code Linter实现代码检查

codelinter检查的结果,用户可以选择不改,又或者不想检查出来,就可以/* eslint-disable */屏蔽,但只能屏蔽有Ignore图标的。在工程根目录下创建code-linter.json5配置文件,可对于代码检查的范围及对应生效的检查规则进行配置,ruleSet和rules配置项共同确定了生效的 规则范围。在已打开的代码编辑器窗口单击右键点击Code Linter,或在工程管理窗口中鼠标选中单个或多个工程文件/目录,右键选择Code Linter执行代码检查。

CTrup的博客 743

C#线程(异步委托)

https://www.cnblogs.com/tlmbem/p/10832853.html delegate匿名方法(匿名函数) 1. 函数和方法等价。匿名方法能够让你声明一个方法体而不需要给它指定一个名字,它们以一个“普通的”方法存在,但是在你的代码中没有任何方法显式调用它。,返回参数不需要声明,会根据[语句块]决定。 2. 匿名方法只能在使用委托的时候创建,它们通过delegate关键字创建或者Lambda表达式(匿名函数)。定义方式:delegate(显式参数,显式参数) {语句块}

爱她就要努力 2408

HarmonyOS 开发实践 —— 基于Code Linter实现代码检查

codelinter检查的结果,用户可以选择不改,又或者不想检查出来,就可以/* eslint-disable */屏蔽,但只能屏蔽有Ignore图标的。在工程根目录下创建code-linter.json5配置文件,可对于代码检查的范围及对应生效的检查规则进行配置,ruleSet和rules配置项共同确定了生效的 规则范围。在已打开的代码编辑器窗口单击右键点击Code Linter,或在工程管理窗口中鼠标选中单个或多个工程文件/目录,右键选择Code Linter执行代码检查。

liuhaojiabin的博客 1107

嵌入式开发:成功进行代码审查的10个问题

多年来,开发人员在审查代码时有一些常见的问题,无论公司的规模有多大,开发过程有多成熟,总会出现问题。为了帮助缓解这些常见问题,嵌入式开发人员在审查C代码时可以提出一下10个问题,以帮助找到潜在的bug问题。...

yueqian_edu的博客 371

【亲测免费】 提升嵌入式系统C代码质量的利器:嵌入式系统C代码走查检查单

提升嵌入式系统C代码质量的利器:嵌入式系统C代码走查检查单 【下载地址】嵌入式系统C代码走查检查单分享 嵌入式系统C代码走查检查单 项目地址: https://gitcode.com/Open-source-documentati...

gitblog_06650的博客 474

58、嵌入式软件开发的并发、检查、评审、测试及问题跟踪

本文深入探讨了嵌入式软件开发中的多个关键环节,包括并发控制与互斥锁的使用、可重入代码的设计与实现、静态检查与编译器警告的处理、同行评审的流程与优化、测试计划的制定与测试自动化,以及问题跟踪与缺陷分析的最佳实践。通过这些方法,可以有效提高软件质量与开发效率,确保嵌入式系统在各种环境下稳定运行。

mqtt6iot的博客 50

嵌入式代码静态检查和AI审核工具汇总

摘要:本文汇总了嵌入式开发领域主流静态代码检测工具和AI辅助工具,涵盖商业与开源方案。重点推荐了Parasoft C/C++test、GrammaTech CodeSonar等专业工具,以及Cppcheck、Clang-Tidy等开源方案,同时介绍了GitHub Copilot、字节跳动Trae等AI工具。各工具在检测深度、适用场景、价格等方面存在差异,开发者可根据项目安全性要求、预算和团队规模灵活选择。文章特别强调汽车电子、医疗设备等安全关键领域需优先考虑具备功能安全认证的商业工具,而预算有限团队可选用开

SDFangFang2025的博客 746

使用CI/CD集成cppcheck进行嵌入式Linux开发的代码静态检查

通过将cppcheck集成到嵌入式Linux开发的CI/CD流程中,我们可以自动化进行代码静态检查,帮助开发者及早发现并修复潜在的代码问题。通过使用代码静态分析工具如cppcheck,开发者可以提高嵌入式Linux开发的代码质量和可靠性,从而减少潜在的错误和问题。cppcheck是一个流行的开源静态代码分析工具,它可以帮助开发者检测C/C++代码中的各种错误和潜在问题。现在,我们可以将上述脚本添加到项目的CI/CD配置中,并在每次提交或构建时运行cppcheck。你可以根据需要进行调整和修改。

DaxqScratch的博客 449

【开发工程篇】CPP代码检查工具

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对CPP代码检查工具做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。

qq_35635374的博客 274

【亲测免费】 嵌入式系统C代码走查检查单

嵌入式系统C代码走查检查单 【下载地址】嵌入式系统C代码走查检查单分享 嵌入式系统C代码走查检查单 项目地址: https://gitcode.com/Open-source-documentation-tutorial/cce4...

gitblog_06675的博客 443

C# 异步委托 四步走

00--简单的异步委托 01--带回调函数 02--带返回值的异步委托 03--带返回值的泛型异步委托

嵌入式代码静态检查

嵌入式开发优选cppcheck内存泄漏、数组越界、未初始化变量、空指针、资源未释放、格式字符串漏洞。设置: Edit->Preference->Language 可以设置中文简体.重新打开一个终端可以查到cppcheck版本号,证明环境变量设定完成。双击运行即可对该工程进行代码分析检查。在对应工程目录下建立.bat文件。下载并双击安装即可。

yongyuanziwo的博客 286

debian linux系统安装教程,Debian 10(Buster)安装过程图文详解

Debian 项目发布了它的最新稳定版 Debian 10,其代号是 “Buster”,这个发布版将获得 5 年的支持。Debian 10 可用于 32 位和 64 位系统。这个发布版带来很多新的特色,列出下面一些特色:引入新的 Debian 10 的主题 “FuturePrototype”新版本的电脑桌面环境 GNOME 3.30、Cinnamon 3.8、KDE Plasma 5.14、MAT...

weixin_39864601的博客 4985

HFSS实战(二)——精准仿真高速PCB差分线的信号完整性

本文深入探讨了使用HFSS进行高速PCB差分线信号完整性仿真的关键技术与实战经验。从设计文件导入、模型裁剪到差分端口设置,详细解析了精准仿真的全流程,特别强调了材料特性和3D电磁场仿真在解决微带线损耗等问题中的重要性。文章还提供了常见问题排查指南和效率优化技巧,帮助工程师提升高速PCB设计的仿真精度与效率。

weixin_38170829的博客 574

嵌入式代码安全检查:选if还是assert?

如果没有定义宏 NDEBUG,那么 assert() 宏将会把一些检查代码进行替换,我们在开发阶段执行 debug 模式编译时,一般都会屏蔽掉这 NDEBUG 这个宏。今天就给大家分享一下相关的内容。:以上这 2 种检查方式,在实际的代码中都很常见,从功能上来说似乎也没有什么影响。,当在 release 阶段编译代码的时候,都会在编译选项中(Makefile)定义这个宏。,我就预料到调用者会乱搞,故意的传入一些无效参数,来测试我的编码水平。2. 如果宏的参数是零值,就打印诊断消息,然后调用abort()。

strongerHuang 260

ES8311音频Codec避坑指南:从I2C通信、电平匹配到回环测试的保姆级调试笔记

本文详细解析了ES8311音频编解码芯片的调试全流程,涵盖I2C通信建立、电平匹配、主从模式配置等关键环节。通过真实案例和实用技巧,帮助工程师快速定位和解决音频Codec常见问题,提升硬件调试效率。特别针对回环测试、功耗分析等高频故障点提供了可复用的排查方法论。

weixin_42532938的博客 275

C++项目工程代码自动检查

在一个大型C++项目中,开发团队面临着频繁的代码错误和维护成本高的问题。该项目涉及多个模块,团队成员众多。通过几个月的使用,团队发现代码错误减少了40%,重构成本降低了30%。通过详细的质量报告,团队能够识别技术债务,并进行针对性改进。

好看资源网的博客 1853

独立站如何采集商品?外贸独立站采集教程

从这里Robert了解到还有国内有很多仿牌卖家、微商,都有类似的情况,他们出海的阻碍主要在于支付、物流、推广。8.插件“抓取任务”列表手动点同步,将商品同步到主商城后台商品管理列表(商品默认同步到下架列表中) 后台商品管理下架列表显示已同步商品。5.店铺信息修改完成后,可以开始采集商品,采集时弹窗中会自动识别当前平台及商品链接,分类和相册名称可以自定义 编辑修改。4. 打开采集目标站商品页面,点开谷歌浏览器扩展程序列表,找到Shopyy采集平台,打开配置页。打开弹窗中的“店铺管理”,添加店铺信息。

Jernnifer_mao的博客 1379

Android应用之【巧妙隐藏桌面图标的进阶方案】

本文详细探讨了Android应用中隐藏桌面图标的进阶方案,解决了传统方法在Android 10及以上版本中出现的黑色图标残留问题。通过Intent-Filter配置和厂商适配技巧,实现子应用真正隐身,同时确保主应用正常启动。适用于企业工具套件、模块化系统等场景,提升用户体验和安全性。

weixin_28363123的博客 508

嵌入式问题分析思路

代码有问题?该如何快速精准的找到问题呢?

weixin_58602623的博客 1554

基于MATLAB的井筒多相流模拟

井筒多相流的模拟可以基于不同的数学模型和计算方法。其中,最常用的模型之一是多相流模型,它基于质量守恒、动量守恒和能量守恒等原理,描述了流体在井筒中的流动行为。对于井筒多相流的模拟和分析可以帮助我们理解和优化油气田开发过程中的流体行为,从而提高产量和效率。在本文中,我们将介绍如何使用MATLAB进行井筒多相流的模拟,并提供相应的源代码。需要注意的是,以上示例是一个简化的模拟,仅用于演示如何使用MATLAB进行井筒多相流模拟。实际应用中,我们需要考虑更多的物理过程和参数,并使用更复杂的数值方法和模型进行模拟。

AtdiHtml的博客 706

AI代码规则(嵌入式)

在 AI 辅助开发普及与跨领域工程融合的背景下,传统代码分析规范已难以适配嵌入式、电子工程、软件开发等多场景需求。本文基于 "精准适配、可控协作、全域验证" 原则,构建覆盖多领域的代码分析规范体系,旨在提升分析准确性与解决方案落地效率,平衡技术严谨性与工程实用性。实施过程中需结合具体领域特性灵活调整,持续收集实践反馈优化规范细节,最终实现代码分析的精准化、解决方案的高效化与跨角色协作的顺畅化,为多领域工程质量提升提供支撑。一、核心原则:强化领域适配与 AI 协同可控性​。(一)分析质量控制​。

smyhhh123456的博客 1231

使用Simulink进行基于IIR滤波器的设计与稳定性分析仿真

IIR滤波器的稳定性与其系统函数的极点位置密切相关。如果所有极点都位于Z平面的单位圆内,则该滤波器是稳定的;否则,滤波器将是不稳定的。在设计IIR滤波器时,确保其稳定性对于避免输出信号发散至关重要。明确你的系统需求,比如输入信号类型(如正弦波)、采样率、IIR滤波器的设计参数(如滤波器类型、阶数、截止频率等)。假设我们需要设计一个低通IIR滤波器,用来去除高于500Hz的所有频率成分,保留低于500Hz的信号成分。采样率为8kHz。

xiaoheshang_123的博客 150

虚幻商城 Quixel 免费资产一键入库

在免费领取所有Megascans之后,我们只是有了获取 Quixel Megascans 资产的资格,但是没有入 Fab 库,本文将讲解通过脚本将 Quixel 所有资产入库 Fab。

一碗清深的博客 3337
上一篇: 应用程序部署总结
下一篇: 如何快速正确的安装 Ruby, Rails 运行环境
watkins
博客等级 码龄18年 1277粉丝 246原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值