【C# .NET】chapter 13 使用多任务改进性能和可扩展性

news2024/11/17 19:39:42

目录

一、物理内存和虚拟内存使用(Recorder 类)

二、 对比 string的“+”操作与stringbuilder 操作 的处理效率,内存消耗情况,

三、异步运行任务、三种启动任务方法、将上一任务方法处理结果作为参数传给下一任务方法

四、嵌套子任务

五、同步访问共享资源  Monitor.TryEnter、Monitor.Exit、 原子操作 Interlocked.Increment

六、理解async  和 await  :改进控制台响应。  Main方法async Task 

七、支持多任务的普通类型

 八、异步流   返回类型IEnumerable


一、物理内存和虚拟内存使用(Recorder 类)

using System;
using System.Diagnostics;
using static System.Console;
using static System.Diagnostics.Process;

namespace Packt.Shared
{
    public static class Recorder
    {
        static Stopwatch timer = new Stopwatch();
        static long bytesPhysicalBefore = 0;
        static long bytesVirtualBefore = 0;

        public static void Start()
        {
            // force two garbage collections to release memory that is no
            // longer referenced but has not been released yet
            // // 强制两次垃圾回收释放不再被引用但尚未释放的内存
            GC.Collect();
            GC.WaitForPendingFinalizers();//挂起当前线程,直到正在处理终结器队列的线程清空该队列。
            GC.Collect();//强制立即对所有代进行垃圾回收。

            //存储当前物理和虚拟内存使用 store the current physical and virtual memory use
            bytesPhysicalBefore = GetCurrentProcess().WorkingSet64;
            bytesVirtualBefore = GetCurrentProcess().VirtualMemorySize64;
            timer.Restart();
        }

        public static void Stop()
        {
            timer.Stop();
            long bytesPhysicalAfter = GetCurrentProcess().WorkingSet64;//计时停止时的 物理内存和虚拟内存使用
            long bytesVirtualAfter = GetCurrentProcess().VirtualMemorySize64;

            WriteLine("{0:N0} physical bytes used.",
              bytesPhysicalAfter - bytesPhysicalBefore);

            WriteLine("{0:N0} virtual bytes used.",
              bytesVirtualAfter - bytesVirtualBefore);

            WriteLine("{0} time span ellapsed.", timer.Elapsed);

            WriteLine("{0:N0} total milliseconds ellapsed.",
              timer.ElapsedMilliseconds);//获取当前实例测量的总运行时间,以毫秒为单位。
        }
    }
}

二、 对比 string的“+”操作与stringbuilder 操作 的处理效率,内存消耗情况,

using System;
using System.Linq;
using Packt.Shared;
using static System.Console;

namespace MonitoringApp
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
            WriteLine("Processing. Please wait...");
            Recorder.Start();

            // simulate a process that requires some memory resources...
            int[] largeArrayOfInts = Enumerable.Range(1, 10_000).ToArray();

            // ...and takes some time to complete
            System.Threading.Thread.Sleep(new Random().Next(5, 10) * 1000);

            Recorder.Stop();
            */

            int[] numbers = Enumerable.Range(1, 50_000).ToArray();//生成指定范围内的整数序列。

            WriteLine("Using string with +");
            Recorder.Start();
            string s = "";
            for (int i = 0; i < numbers.Length; i++)
            {
                s += numbers[i] + ", ";
            }
            Recorder.Stop();

            /*
            Using string with +
            35,196,928 physical bytes used.
            6,291,456 virtual bytes used.
            00:00:04.0648349 time span ellapsed.
            4,064 total milliseconds ellapsed.
            Using StringBuilder
            0 physical bytes used.
            0 virtual bytes used.
            00:00:00.0018665 time span ellapsed.
            1 total milliseconds ellapsed.
             */
            WriteLine("Using StringBuilder");
            Recorder.Start();
            var builder = new System.Text.StringBuilder();

            for (int i = 0; i < numbers.Length; i++)
            {
                builder.Append(numbers[i]); builder.Append(", ");
            }
            Recorder.Stop();
            ReadLine();
        }
    }
}

三、异步运行任务、三种启动任务方法、将上一任务方法处理结果作为参数传给下一任务方法

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using static System.Console;

namespace WorkingWithTasks
{
    class Program
    {
        static void MethodA()
        {
            WriteLine("Starting Method A...");
            Thread.Sleep(3000); // simulate three seconds of work 
            WriteLine("Finished Method A.");
        }

        static void MethodB()
        {
            WriteLine("Starting Method B...");
            Thread.Sleep(2000); // simulate two seconds of work 
            WriteLine("Finished Method B.");
        }

        static void MethodC()
        {
            WriteLine("Starting Method C...");
            Thread.Sleep(1000); // simulate one second of work 
            WriteLine("Finished Method C.");
        }

        static decimal CallWebService()
        {
            WriteLine("Starting call to web service...");
            Thread.Sleep((new Random()).Next(2000, 4000));
            WriteLine("Finished call to web service.");
            return 89.99M;
        }

        static string CallStoredProcedure(decimal amount)
        {
            WriteLine("Starting call to stored procedure...");
            Thread.Sleep((new Random()).Next(2000, 4000));
            WriteLine("Finished call to stored procedure.");
            return $"12 products cost more than {amount:C}.";
        }

        static void Main(string[] args)
        {
            var timer = Stopwatch.StartNew();

            //   WriteLine("Running methods synchronously on one thread.");

            //   MethodA();
            //   MethodB();
            //   MethodC();

            /*   //开启任务的三种方法
            WriteLine("Running methods asynchronously on multiple threads.");

            Task taskA = new Task(MethodA);
            taskA.Start();

            Task taskB = Task.Factory.StartNew(MethodB);
            Task taskC = Task.Run(new Action(MethodC));

            Task[] tasks = { taskA, taskB, taskC };
            Task.WaitAll(tasks);
            */

            WriteLine("Passing the result of one task as an input into another.");
            //将CallWebService的结果作为输入传给CallStoredProcedure任务
            var taskCallWebServiceAndThenStoredProcedure =
              Task.Factory.StartNew(CallWebService)
                .ContinueWith(previousTask =>
                  CallStoredProcedure(previousTask.Result));

            WriteLine($"Result: {taskCallWebServiceAndThenStoredProcedure.Result}");

            WriteLine($"{timer.ElapsedMilliseconds:#,##0}ms elapsed.");
            ReadLine();
        }
    }
}

四、嵌套子任务

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using static System.Console;

namespace NestedAndChildTasks
{
  class Program
  {
    static void OuterMethod()
    {
      WriteLine("Outer method starting...");
      var inner = Task.Factory.StartNew(InnerMethod,
        TaskCreationOptions.AttachedToParent);//开启嵌套任务
      WriteLine("Outer method finished.");
    }

    static void InnerMethod()//嵌套子任务方法
    {
      WriteLine("Inner method starting...");
      Thread.Sleep(2000);
      WriteLine("Inner method finished.");
    }

    static void Main(string[] args)
    {
      var outer = Task.Factory.StartNew(OuterMethod);
      outer.Wait();//等待嵌套子任务完成后才继续
      WriteLine("Console app is stopping.");
    }
  }
}

五、同步访问共享资源  Monitor.TryEnter、Monitor.Exit、 原子操作 Interlocked.Increment

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using static System.Console;

namespace SynchronizingResourceAccess
{
    class Program
    {
        static Random r = new Random();
        static string Message; // 一个共享资源
        static int Counter; //另一共享资源
        static object conch = new object();//互斥锁

        static void MethodA()
        {
            try
            {   //在指定的时间内尝试获取指定对象的独占锁。
                if (Monitor.TryEnter(conch, TimeSpan.FromSeconds(15)))
                {
                    for (int i = 0; i < 5; i++)
                    {
                        Thread.Sleep(r.Next(2000));
                        Message += "A";
                        Interlocked.Increment(ref Counter);//递增指定变量并将结果存储为原子操作。
                        Write(".");
                    }
                }
                else
                {
                    WriteLine("Method A failed to enter a monitor lock.");
                }
            }
            finally
            {
                Monitor.Exit(conch);//释放指定对象上的独占锁。
            }
        }

        static void MethodB()
        {
            try
            {
                if (Monitor.TryEnter(conch, TimeSpan.FromSeconds(15)))
                {
                    for (int i = 0; i < 5; i++)
                    {
                        Thread.Sleep(r.Next(2000));
                        Message += "B";
                        Interlocked.Increment(ref Counter);
                        Write(".");
                    }
                }
                else
                {
                    WriteLine("Method B failed to enter a monitor lock.");
                }
            }
            finally
            {
                Monitor.Exit(conch);
            }
        }

        /*
        Please wait for the tasks to complete.
        ..........
        Results: AAAAABBBBB.
        9,083 elapsed milliseconds.
        10 string modifications.
        */
        static void Main(string[] args)
        {
            WriteLine("Please wait for the tasks to complete.");
            Stopwatch watch = Stopwatch.StartNew();

            Task a = Task.Factory.StartNew(MethodA);
            Task b = Task.Factory.StartNew(MethodB);

            Task.WaitAll(new Task[] { a, b });

            WriteLine();
            WriteLine($"Results: {Message}.");
            WriteLine($"{watch.ElapsedMilliseconds:#,##0} elapsed milliseconds.");
            WriteLine($"{Counter} string modifications.");
            ReadLine();
        }
    }
}

 

六、理解async  和 await  :改进控制台响应。  Main方法async Task 

从C#6开始可以在try\catch块中使用await

using System;
using System.Net.Http;
using System.Threading.Tasks;
using static System.Console;

namespace AsyncConsole
{
  class Program
  {
    static async Task Main(string[] args)
    {
      var client = new HttpClient();

      HttpResponseMessage response =
        await client.GetAsync("http://www.apple.com/");

      WriteLine("Apple's home page has {0:N0} bytes.",
        response.Content.Headers.ContentLength);
    }
  }
}

七、支持多任务的普通类型

 八、异步流   返回类型IEnumerable

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using static System.Console;

namespace AsyncEnumerable
{
  class Program
  {
    async static IAsyncEnumerable<int> GetNumbers()
    {
      var r = new Random();

      // simulate work
      await Task.Run(() => Task.Delay(r.Next(1500, 3000)));
      yield return r.Next(0, 1001);

      await Task.Run(() => Task.Delay(r.Next(1500, 3000)));
      yield return r.Next(0, 1001);

      await Task.Run(() => Task.Delay(r.Next(1500, 3000)));
      yield return r.Next(0, 1001);
    }

    static async Task Main(string[] args)
    {
      await foreach (int number in GetNumbers())
      {
        WriteLine($"Number: {number}");
      }
    }
  }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/442139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

妙记多 Mojidoc |构建企业和个人专属知识库

虽然市面上有很多项目管理工具&#xff0c;但对于小公司或初创企业来说&#xff0c;它们要么年费太贵&#xff0c;要么流程和操作太复杂&#xff0c;无法满足小团队的需求。 如果您有基本需求并希望使用低成本的文档工具&#xff0c;作为团队共享知识库和工作流程管理的工具&a…

【GIS学习笔记】快速上手GeoServer,并发布 Shapefile /PostGis / PostgreSQL

文章目录 安装配置1、下载2、配置环境 快速上手 &#xff08;Shapfile文件发布&#xff09;1、登录2、图层预览 Layer Preview3、发布Shapefile4、创建工作空间Workspace5、创建一个 Store&#xff08;数据存储&#xff09;6、创建图层报错解决 7、发布图层 快速上手&#xff0…

一款表现不佳的游戏,如何能爆火出圈?

根据《2022年中国游戏产业报告》&#xff0c;2022年中国游戏市场实际销售收入2658.84亿元&#xff0c;同比下降10.33%。游戏用户规模6.64亿&#xff0c;同比下降0.33%。继2021年规模增长明显放缓之后&#xff0c;又出现过去八年来的首次下降&#xff0c;表明产业发展已进入存量…

使用Dom元素的animate实现无限滚动列表

一、需求 实现一个内容重复滚动的列表&#xff0c;鼠标hover时滚动停止&#xff0c;鼠标移走&#xff0c;继续滚动 二、实现逻辑与代码 这个需求用到了一个dom API&#xff08;animate&#xff09;&#xff0c;这个方法可以用来做过渡动画、关键帧动画&#xff0c;接收两个参…

全景丨0基础学习VR全景制作,平台篇第八章:全局功能-说一说管理

一、功能说明 蛙色VR的全景能够允许用户发布说一说&#xff0c;这些说一说的信息会同步呈现在全景中。 鼓励用户参与到内容中来&#xff0c;增强了全景的互动性&#xff0c;体验感更好&#xff0c;也更容易引导用户分享。 此外&#xff0c;后台系统可以对说一说进行必要的审核…

C++数据结构:二叉搜索树的结构、模拟实现及应用

目录 一. 二叉搜索树的结构 二. 二叉搜索树的模拟实现 2.1 二叉搜索树的节点及类的成员变量 2.2 数据插入操作Insert的实现 2.3 数据删除操作Erase的实现 2.4 数据查找操作Find的实现 2.5 中序遍历InOrder的实现 2.6 构造函数的实现 2.7 析构函数的实现 三. 二叉搜…

第三方软件测试公司与开发人员在进行测试时有什么不一样?

随着科技信息的发展&#xff0c;软件企业要想在市场上站住脚&#xff0c;就必须在产品质量上下功夫。高质量的软件也是开发、测试、质量保证等相关人员共同追求的目标&#xff0c;用户往往会选择体验性、服务性以及安全性较强的软件产品。软件测试可以很好的检测出软件质量&…

基于web的小型餐厅餐饮饭馆供货订货系统asp.net+sqlserver

本研究课题重点主要包括了下面几大模块&#xff1a;用户登录&#xff0c;管理员信息管理&#xff0c;类别信息管理&#xff0c;商家信息管理&#xff0c;商品信息管理&#xff0c;订单信息管理&#xff0c;损耗信息管理&#xff0c;退货信息管理&#xff0c;修改密码等功能。。…

2023-热门ChatGPT解析及使用方法

什么是Chat GPT&#xff1f;我们能用它来干什么&#xff1f; Chat GPT是一款基于人工智能技术的自然语言处理模型&#xff0c;由OpenAI团队开发。它能够通过机器学习技术从海量文本数据中学习语言知识&#xff0c;实现自然语言生成、对话生成和语言理解等功能&#xff0c;使得…

144. 二叉树的前序遍历【78】

难度等级&#xff1a;容易 上一篇算法&#xff1a; 102. 二叉树的层序遍历【206】 力扣此题地址&#xff1a; 144. 二叉树的前序遍历 - 力扣&#xff08;Leetcode&#xff09; 1.题目&#xff1a;144. 二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前…

电源常识-PCB材质防火等级焊锡工艺

1、目前主流的PCB材质分类主要有以下几种,如图1&#xff0c;图2&#xff0c;图3。FR-4材质比CEM-1好&#xff0c;CEM-1比FR-1好。 按结构分为单面板&#xff0c;双面板&#xff0c;多层板。单面板就是单面铺铜走线&#xff0c;双面板就是上下两面都可以铺铜走线&#xff0c;多层…

JavaWeb综合案例

综合案例 1 查询所有 1.1 后端实现 1.1.1 dao方法实现 在 com.itheima.mapper.BrandMapper 接口中定义抽象方法&#xff0c;并使用 Select 注解编写 sql 语句 /*** 查询所有* return*/ Select("select * from tb_brand") List<Brand> selectAll();由于表中…

leetcode 376. 摆动序列

思路没想到就很难&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;看了题解就觉得&#xff0c;还可以 加个图吧&#xff0c;贪心这玩意。。 我之前的困惑就在于&#xff1a; 不知道如何判断 正负规律&#xff0c;发现我双指针的思想用错了。 我一开…

react-7 组件库 Ant Design

1.安装组件库 npm install --save antd-mobile 常用组件 tabbar 底部导航 Swiper 轮播图&#xff08;走马灯&#xff09; NavBar&#xff08;顶部返回累&#xff09; 配合 Dialog&#xff0c;Toast InfiniteScroll 无限滚动&#xff08;实现下拉刷新&#xff09; Skeleto…

沃顿商学院6个最受欢迎的工商管理课程

沃顿商学院创立于1881年&#xff0c;是美国第一所大学商学院。它的故事开始于企业家约瑟夫沃顿&#xff08;Joseph Wharton&#xff09;&#xff0c;他出生于一个费城富有的商业家庭&#xff0c;通过经营佰利恒钢铁公司和美国镍公司积累了大量的财富。在1881年他55岁时&#xf…

借由Net5.5G,看到运营商的新沧海

我们都记得这样一句诗&#xff1a;“东临碣石&#xff0c;以观沧海”。 想要看到沧海的壮阔波澜&#xff0c;就先要抵达碣石山这样可以看到大海的地方。在数字化的发展过程中&#xff0c;往往一个技术或产业趋势就是一座碣石山&#xff0c;借由它可以看到描绘着未来机遇的新沧海…

pandas笔记:tseries.offset

进行date的偏移 1 各种offset 1.1 DateOffset 1.1.1 基本使用方法 class pandas.tseries.offsets.DateOffset n 偏移量表示的时间段数。 如果没有指定时间模式&#xff0c;则默认为n天。 normalize是否将DateOffset偏移的结果向下舍入到前一天午夜**kwds 添加到偏移量的时…

ROS学习第十节——参数服务器

前言&#xff1a;本小节主要是对于参数服务器参数的修改&#xff0c;需要掌握操作参数的函数使用 1.基本介绍 参数服务器实现是最为简单的&#xff0c;该模型如下图所示,该模型中涉及到三个角色: ROS Master (管理者)Talker (参数设置者)Listener (参数调用者) ROS Master …

Bootstrap02 家居商城首页之最新上架热门家具分类页面

目录 案例1&#xff1a;首页最新上架&热门家居实现 案例2&#xff1a;分类页面搜索区域Bootstrap实现&栅格框架搭建 案例3&#xff1a;分类页面分类列表实现&整合 案例1&#xff1a;首页最新上架&热门家居实现 ①.页面内容&#xff1a;画像 Figure ②.组件…

C learning_7

目录 1.for循环 1.虽然while循环和for循环本质上都可以实现循环&#xff0c;但是它们在使用方法和场合上还是有一些区别的。 2.while循环中存在循环的三个必须条件&#xff0c;但是由于风格的问题使得三个部分很可能偏离较远&#xff0c;这样 查找修改就不够集中和方便。所以…