C#多线程

C#多线程

C#多线程是C#学习中必不可少的知识,在实际开发中也能有效的提升用户体验,和程序性能。


文章目录

  • C#多线程
  • 前言
  • 一、什么是线程、什么是进程、什么是协程?
    • 协程
      • 优点
      • 缺点
    • 线程
      • 优点
      • 缺点:
    • 进程
      • 优点
      • 缺点:
  • 二、C# 中线程的使用
    • 委托创建线程
    • Thread类创建线程
    • 线程池创建线程
    • 任务创建线程
  • 总结


前言

随着业务的不断发展,程序的数据处理量需求也越来越高,例如,电商项目中的库存同步,和商品信息拉取等,一个门店都是几千个品种,每个品种都有几十甚至上百的的批次,如果是个连锁有一万家门店,那么这种情况库存同步如果用单线程处理的话效率是极其低的,同步几天都同步不完,接下来就该利用多线程来优化了。


一、什么是线程、什么是进程、什么是协程?

在这里插入图片描述

协程

协程,英文名是 Coroutine, 又称为微线程,是一种用户态的轻量级线程。协程不像线程和进程那样,需要进行系统内核上的上下文切换,协程的上下文切换是由程序员决定的。

优点

  • 无需系统内核的上下文切换,减小开销;
  • 无需原子操作锁定及同步的开销,不用担心资源共享的问题;
  • 单线程即可实现高并发,单核 CPU 即便支持上万的协程都不是问题,所以很适合用于高并发处理,尤其是在应用在网络爬虫中。

缺点

  • 无法使用 CPU 的多核

协程的本质是个单线程,它不能同时用上单个 CPU 的多个核,协程需要和进程配合才能运行在多 CPU上。当然我们日常所编写的绝大部分应用都没有这个必要,就比如网络爬虫来说,限制爬虫的速度还有其他的因素,比如网站并发量、网速等问题都会是爬虫速度限制的因素。除非做一些密集型应用,这个时候才可能会用到多进程和协程。

  • 处处都要使用非阻塞代码

写协程就意味着你要一直写一些非阻塞的代码,使用各种异步版本的库,比如后面的异步爬虫教程中用的 aiohttp 就是一个异步版本的request库等。 不过这些缺点并不能影响到使用协程的优势。

线程

线程,英文名是Thread,线程是进程中的一个实体,作为系统调度和分派的基本单位。Linux下的线程看作轻量级进程。
它是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。

优点

  • 创建一个新线程的代价比创建一个新进程要小的多;
  • 与进程相比,线程之间的切换需要操作系统做的工作要少很多;
  • 线程占用的资源要比进程少很多;
  • 能充分利用多处理器的可并行数量;
  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务;
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现;
  • I/O密集型应用,为了能提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

缺点:

  • 性能损失

一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器,如果计算密集型线程的数量比可用的处理器多,那么可能会有较大性能损失,性能损失只增加了额外的同步和调度开销,而可用资源不变。

  • 健壮性降低

编写多线程需要更全面深入的考虑,在一个多线程程序里面,因时间分配上的细微偏差或者因为共享了不该共享的变量造成的影响很大,线程是缺乏保护的;

  • 缺乏访问控制

进程是访问控制的基本粒度,在一个线程中调用某些OD函数会对整个进程造成影响;

  • 编程难度提高

调试多线程程序比单线程程序困难的多。

进程

进程,英文名是:process,当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。

优点

  • 顺序程序的特点:具有封闭性和可再现性;

  • 程序的并发执行和资源共享。多道程序设计出现后,实现了程序的并发执行和资源共享,提高了系统的效率和系统的资源利用率。

缺点:

  • 操作系统调度切换多个线程要比切换调度进程在速度上快的多。而且进程间内存无法共享,通讯也比较麻烦。

  • 在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

它们之间的关系如下:
进程可以包含多个线程,线程里又可以包含多个协程
在这里插入图片描述

二、C# 中线程的使用

在C#中创建线程的方式:

  • 利用委托创建线程
  • 利用Thread类创建线程
  • 利用线程池创建线程
  • 利用任务创建线程

委托创建线程

.net Core.net Framework
不支持支持

.net Framework 示例代码:

Func<int, int, int> a = (d, b) => d + b;
a.BeginInvoke(3, 4, CallBack, a);
Console.ReadKey();
static void CallBack(IAsyncResult ar) //系统会自动将该参数填充
{Func<int, int, int> b = ar.AsyncState as Func<int, int, int>;int res = b.EndInvoke(ar);Console.WriteLine("最后得到的结果是:" + res);
}

虽然.net Core 不可以但是这里还是给大家展示
微软官网文档
以下是.net Core6.0实现委托实现AOP的方法

using System.Reflection;DelegateExtension extension = new DelegateExtension();
Console.WriteLine(extension.Show());
Console.WriteLine("主线程执行...");
Console.Read();public abstract class BaseAttribute : Attribute
{public abstract Func<int> Do(Func<int> action);}
public class BeforAttribute : BaseAttribute
{public override Func<int> Do(Func<int> action){Console.WriteLine("执行之前基础操作!");Func<int> acc = new Func<int>(action.Invoke);return acc;}
}public class CoreFunc
{[Befor]public int Methond(){Console.WriteLine("主要执行的方法");return 1;}}
public class DelegateExtension
{public int Show(){CoreFunc ca = new CoreFunc();//反射对象Type type = ca.GetType();MethodInfo methodInfo = type.GetMethod("Methond");Func<int> action = () => { return Convert.ToInt32(methodInfo.Invoke(ca, null)); };//判断这个方法上面是否有BeforAttribute 特性,没有就直接执行方法 if (methodInfo.IsDefined(typeof(BeforAttribute), true)){foreach (BaseAttribute ba in methodInfo.GetCustomAttributes(typeof(BaseAttribute), true)){action = ba.Do(action);}}return action.Invoke();}}

执行结果如下:
在这里插入图片描述

Thread类创建线程

.net Core.net Framework
支持支持

以下是代码示例

string name = "子线程传入的参数";
Thread t = new Thread(() => Console.WriteLine(name));
t.Start();
Console.WriteLine("主线程执行");
Console.ReadLine();

执行结果如下:
在这里插入图片描述

线程池创建线程

.net Core.net Framework
支持支持
void ThreadMethod(object name) { Console.WriteLine("子线程线程ID:" + Thread.CurrentThread.ManagedThreadId.ToString("00")); }
ThreadPool.QueueUserWorkItem(ThreadMethod);
Console.WriteLine("主线程执行");Console.ReadLine();

执行结果如下:
在这里插入图片描述

任务创建线程

.net Core.net Framework
支持支持
//第一种方法
Task task = new Task(() => { Console.WriteLine("第一种方法输出!"); });
task.Start();
//第二种方法
TaskFactory taskF = new TaskFactory();
taskF.StartNew(() => Console.WriteLine("第二种方法输出!"));//连续型任务(按顺序执行)
Task task = new Task(() => Console.WriteLine("你好"));
task.Start();
Task task2 = task.ContinueWith((a) => Console.WriteLine("hello"));Console.ReadLine();

执行结果:
在这里插入图片描述

参考自”猫不在“博主博客


总结

以上就是线程的一些基础知识,线程涉及的知识还是比较广的,比如线程资源争夺,线程锁,线程权重等知识,后面我会为大家分享并拿实际案例来讲解。

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

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

相关文章

使用Spring Boot实现Redis键过期回调功能

使用Spring Boot实现Redis键过期回调功能 当使用Redis作为缓存或数据存储的时候&#xff0c;有时候需要在键过期时执行一些特定的操作&#xff0c;比如清除相关数据或发送通知。在Spring Boot中&#xff0c;可以通过实现RedisMessageListener接口来实现Redis键过期回调功能。下…

基于“RWEQ+”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写

查看原文>>>基于“RWEQ”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写 土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一&#xff0c;土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的首要过程。…

B2B企业如何选择CRM系统?

CRM软件的优势在于简化业务流程&#xff0c;实现企业的降本增效。越来越多的B2B企业通过CRM为业务赋能&#xff0c;B2B企业如何快速找到适合公司业务的CRM系统&#xff1f;总的来说就是根据企业自身业务而量身打造的一套系统。 1.整理业务需求 B2B企业首先要考虑是业务痛点&a…

MySQL绿色安装和配置

1、 从地址http://dev.mysql.com/downloads/mysql/中选择windows的版本下载。 2、 mysql各个版本的简介 &#xff08;1&#xff09; MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;但不提供官方技术支持。 &#xff08;2&#xff09; MySQL Enterprise Ed…

Spring MVC

一、什么是MVC MVC就是一种思想&#xff0c;而Spring MVC是对MVC思想的具体实现 MVC是Model View Controller的所缩写&#xff0c;是一种软件架构模式&#xff0c;它将软件系统Fenwick墨香&#xff0c;视图和控制器三个基本部分。 Model&#xff1a;是应用程序中用于处理应用…

7.27 Qt

制作简易小闹钟 Timer.pro QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # dep…

Cisco 路由器配置管理

大多数网络中断的最常见原因是错误的配置更改。对网络设备配置的每一次更改都伴随着造成网络中断、安全问题甚至性能下降的风险。计划外更改使网络容易受到意外中断的影响。 Network Configuration Manager 网络更改和配置管理 &#xff08;NCCM&#xff09;解决方案&#xff…

Python(四十五)二层循环中的break和continue

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

C#之泛型

目录 一、概述 二、C#中的泛型 继续栈的示例 三、泛型类 &#xff08;一&#xff09;声明泛型类 &#xff08;二&#xff09;创建构造类型 &#xff08;三&#xff09;创建变量和实例 &#xff08;四&#xff09;比较泛型和非泛型栈 四、类型参数的约束 &#xff08;一…

elementUI --- el-select 下拉框 日历 级联选择

element UI 组件库中的 select 选择器 中下拉列表的样式&#xff0c;在页面渲染的时候&#xff0c;总是渲染为仅次于body级别的div &#xff0c;这样子覆盖样子会影响全局其他的select选择器下拉框样式&#xff0c;试图通过给el-select加父标签来覆盖&#xff0c;然而并没有卵用…

【FAQ】关于无法判断和区分用户与地图交互手势类型的解决办法

一&#xff0e; 问题描述 当用户通过缩放手势、平移手势、倾斜手势和旋转手势与地图交互&#xff0c;控制地图移动改变其可见区域时&#xff0c;华为地图SDK没有提供直接获取用户手势类型的API。 二&#xff0e; 解决方案 华为地图SDK的地图相机有提供CameraPosition类&…

哈希表及其模拟实现

文章目录 一、解决哈希冲突1.1闭散列1.1.1线性探测1.1.2二次探测 1.2开散列 二、模拟实现哈希表三、HashMap源码的一些相关内容 哈希&#xff08;散列&#xff09;方法&#xff1a;构造一种存储结构&#xff0c;通过某种函数使元素的存储位置与它的关键码之间能够建立 一 一 映…

【JavaWeb】Tomcat底层机制和Servlet运行原理

&#x1f384;欢迎来到dandelionl_的csdn博文&#xff0c;本文主要讲解Java web中Tomcat底层机制和Servlet的运行原理的相关知识&#x1f384; &#x1f308;我是dandelionl_&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一…

HCIA实验二

实验要求&#xff1a; 1.R2为ISP&#xff0c;只能配置IP 2.R1-R2之间为HDLC封装 3.R2-R3之间为PPP封装&#xff0c;pap认证&#xff0c;R2为主认证方 4.R2-R4之间为PPP封装&#xff0c;chap认证&#xff0c;R2为主认证方 5.R1、R2、R3构建MGRE&#xff0c;仅R1的IP地址固定…

【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

Nginx学习&#xff1a;HTTP核心模块&#xff08;九&#xff09;浏览器缓存与try_files 浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置&#xff0c;这一块也是 HTTP 的基础知识。之前我们就一直在强调&#xff0c;学习 Nginx 需要的就是各种网络相关的基础知识&…

AndroidStudio设计一个计算器

界面设计 activity_calcuator.xml 设计&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto&qu…

3ds Max图文教程: 创建致命的冠状病毒动画

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 病毒建模 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 在透视视口中创建一个半径为 50&#xff0c;线段为 20 的 GeoSphere。 创建地球 步骤 3 打开修改器列表并将置换修改器应用于地理 球。 置换…

【STL】模拟实现反向迭代器

目录 1. 读源码 2. 搭建框架 3. 迭代器的操作 operator*() operator->() operator() operator--() operator!() 4. 实现 list 的反向迭代器 5. 实现 vector 的反向迭代器 6. 源码分享 写在最后&#xff1a; 1. 读源码 我们之前实现的 vector&#xff0c;list…

类加载机制,类加载顺序

类加载顺序 ①类加载从上往下执行&#xff0c;依次执行静态的初始化语句和初始化块&#xff0c;而且类加载优先于对象创建。&#xff08;静态初始化语句和初始化块只加载一次&#xff09; ②创建本类的对象时&#xff0c;从上往下执行一次非静态的初始化语句和初始化块&#…

Unity《勇士传说》开发日记:如何制作可互动标识

要实现的需求&#xff1a; 在游戏当中&#xff0c;我们的主角走到宝箱前&#xff0c;可以将宝箱打开&#xff0c;走到洞穴口可以进入下一个场景&#xff0c;此时需要有个互动标识来提示用户。如图所示&#xff1a; 当角色走到宝箱前&#xff0c;弹出互动标识提示用户按下E键可…