C#多线程之旅(4)——APM初探

本文涉及的产品
应用实时监控服务-用户体验监控,每月100OCU免费额度
应用实时监控服务-应用监控,每月50GB免费额度
简介: C#多线程之旅(4)——APM初探

阅读目录

源码地址:https://github.com/Jackson0714/Threads

 

原文地址:C#多线程之旅(4)——APM初探

C#多线程之旅目录:

C#多线程之旅(1)——介绍和基本概念

C#多线程之旅(2)——创建和开始线程

C#多线程之旅(3)——线程池

C#多线程之旅(4)——APM初探

C#多线程之旅(5)——同步机制介绍

C#多线程之旅(6)——详解多线程中的锁

更多文章正在更新中,敬请期待......

 

C#多线程之旅(4)——APM初探

v博客前言

先交代下背景,前面几张内容主要是介绍多线程的基本知识,这一章是因为正好接触到了APM(异步编程模型),发现APM真的很强大,其中有部分知识点涉及到了委托的BeginInvoke/EndInvoke,就由衷地想写下APM相关的知识。

图片.png

v写在前面

强大的异步处理模型,不得不被它折服!

v正文开始

回到顶部

一、简单的串行执行程序

我们先来看一个简单的程序:

定义了一个int Add(int num),传入循环的次数num,返回循环相加的结果sum。

Step 1.Main方法调用Add方法,循环执行了2次,所以延时了2s,返回结果sum=1,打印 Result:1;

Step 2.Main方法循环执行了3次,延时了3s。

友情提醒:如果觉得不想阅读多彩的Console打印代码,可以选择查看下面折叠的code区域。查看简洁版

1.png

去掉颜色打印的code简洁版

2.png

让我们看看这个程序的运行结果:

001.gif

我们可以从结果中看到:

  1.执行Add方法,是主线程执行Add方法;

  2.执行Main方法,是主线程执行Main方法;

  3.这中限时操作可以称为“计算限制的异步操作”;

  4.Add方法中模拟耗时操作(2s)和Main方法中模拟耗时操作(3s)是串行执行的,那么我们有没有一种方法使这两种操作并行执行了?(3s中之内搞定这两个耗时操作)。答案是可以用APM。

 

下面我们用APM方式来节省2s的时间。

回到顶部

二、使用委托来实现APM

2.1 预备知识

我们使用泛型委托来实现APM,那么我们需要点预备知识(对委托很熟练的同学们可以跳过预备知识):

  1.什么是委托?

  2.什么是泛型委托?

  3.为什么使用委托来实现APM?

对于这知识点1、2,可以参考我之前写的博客,在这里就不再说明了,图片.png不惧面试:委托

对于第三个知识点,是因为委托定义了两个异步方法BeginInvokeEndInvoke

我们可以先看看泛型委托的定义:

/// <summary>
/// 定义一个泛型委托
/// </summary>
/// <typeparam name="T">输入参数</typeparam>
/// <typeparam name="TResult">返回值</typeparam>
/// <param name="arg">输入参数</param>
/// <returns name="TResult">返回值</returns>
private delegate TResult Func<T, TResult>(T arg);

对于这个定义,C#编译器会将这行代码编译成一个类定义,它的逻辑定义如下:

public sealed class Func<T, TResult> : MulticastDelegate
{
    public Func(Object obj, IntPtr method);
    public TResult Invoke(T arg);
    public IAsyncResult BeginInvoke(T arg, AsyncCallback callback, Object obj);
    public TResult EndInvoke(IAsyncResult result);
}

定义一个委托时,会生成一个BeginInvoke和EndInvoke方法的类。

当定义下面的委托时

public delegate void myDelegate(int value);

通过反编译工具ILSpy查看结果:

图片.png

BeginInvoke:

  1.第一个参数arg为委托定义相同的参数(可以为两个参数arg,和委托的签名相同),可以传入到委托引用的方法;

  2.倒数第二个参数callback为回调方法,当BeginInvoke方法执行完后,会立即调用回调方法,如果callback=null,则不调用回调方法;

  3.倒数第一个参数object给EndInvoke用的。

  4.返回值为IAsyncResult类型的接口对象(实际上是AsynResult的类型实例)。该接口对象用途

    a.传递参数,它包含了对调用了BeginInvoke的委托的引用,这里是Add方法的int类型的输入参数;

    b.包含了BeginInvoke()的最后一个Object类型的参数

    c.它可以鉴别是哪个方法的哪一次调用,因为通过同一个委托变量可以对同一个方法调用多次。

EndInvoke

  1.第一个参数接收BeginInvoke返回的IAnsyResult;

  2.返回的TResult为委托引用的方法的返回值,这里是Add方法的int类型返回值

2.2 用委托来实现APM的原理

图片.png

2.3 动手写个实现了APM的Code

通过上面的流程图,相信我们对委托来实现APM有了一定的理解,再来读读code,相信能更快地理解。注释仅作参考,有问题可以回复我哦!

图片.png

图片.png

让我们看看结果:

2.gif

注意:

  1.必须先将IAsyncResult转换为AsyncResult,才能获取到引用的委托,因为它没有包含在IAsyncResult接口的定义中;

  2.Add方法的调用,AddCallback方法都是线程池线程调用的;

  3.BeginInvoke的object参数可以为任何类型,例子中传递的是string类型的参数"I'm here!";

  4.主线程执行的for循环和Add方法中线程是同时进行的,交替打印结果;

  5.当异步的Add方法没有执行完毕,调用EndInvoke,则会阻塞当前线程池线程,只有异步方法执行完毕后,才会继续执行的代码;

  6.Add方法执行完后,会自动调用回调方法AddCallback;

  7.在调用EndInvoke可能抛出异常,所以需要加try/catch/finally,捕获EndInvoke的可能抛出的异常。

 

v写在最后

因为只是刚开始接触APM相关的知识,所以本篇只是写初探的内容,后面的章节会更多地介绍这方面的内容。希望得到园友们的支持!




相关实践学习
通过云拨测对指定服务器进行Ping/DNS监测
本实验将通过云拨测对指定服务器进行Ping/DNS监测,评估网站服务质量和用户体验。
相关文章
|
7月前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
204 3
|
7月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
7月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
4月前
|
数据采集 XML JavaScript
C# 中 ScrapySharp 的多线程下载策略
C# 中 ScrapySharp 的多线程下载策略
|
3月前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
86 0
|
4月前
|
安全 C# 开发者
【C# 多线程编程陷阱揭秘】:小心!那些让你的程序瞬间崩溃的多线程数据同步异常问题,看完这篇你就能轻松应对!
【8月更文挑战第18天】多线程编程对现代软件开发至关重要,特别是在追求高性能和响应性方面。然而,它也带来了数据同步异常等挑战。本文通过一个简单的计数器示例展示了当多个线程无序地访问共享资源时可能出现的问题,并介绍了如何使用 `lock` 语句来确保线程安全。此外,还提到了其他同步工具如 `Monitor` 和 `Semaphore`,帮助开发者实现更高效的数据同步策略,以达到既保证数据一致性又维持良好性能的目标。
57 0
|
6月前
|
并行计算 算法 C#
C# Mandelbrot和Julia分形图像生成程序更新到2010-9-14版 支持多线程计算 多核处理器
此文档是一个关于分形图像生成器的介绍,作者分享了个人开发的M-J算法集成及色彩创新,包括源代码和历史版本。作者欢迎有兴趣的读者留言交流,并提供了邮箱(delacroix_xu@sina.com)以分享资源。文中还展示了程序的发展历程,如增加了真彩色效果、圈选放大、历史记录等功能,并分享了几幅精美的分形图像。此外,还提到了程序的新特性,如导入ini文件批量输出图像和更新一批图片的功能。文档末尾附有多张程序生成的高分辨率分形图像示例。
|
6月前
|
大数据 C#
C#实现多线程的几种方式
C#实现多线程的几种方式
|
7月前
|
安全 Java C#
C#多线程详解
C#多线程详解
64 0