09-C#.Net-多线程-基础篇-学习笔记

C#学习之web网站制作入门篇(ASP.NET) 之前熟悉C#与.net, 以为.net就是C#,现在知道了.NET是C#的开发平台,C#即可用来开发客户端(WindowsFrom),也可以用来开发网站即ASP.NET; 阅读详情

一、核心概念理解

1.1 进程与线程

进程(Process)

  • 计算机中的虚拟记录,描述应用程序运行时消耗的各种资源集合
  • 包含:CPU + 内存 + 磁盘IO + 网络资源
  • 类比:一个公司的整体运作

线程(Thread)

  • 程序进程中执行具体动作的最小执行流
  • 从点击按钮到网络通信,都是线程在执行
  • 类比:公司中的具体员工
  • 特点:线程依附于进程存在,进程消失则线程也消失

句柄(Handle)

  • long类型的数字,对应程序中的某个小部件
  • 是操作程序的最小单位标识

1.2 多线程的原理

CPU与多线程

  • 例如:6核12线程的CPU
  • 通过逻辑切分,将每个核心的执行时间分片
  • 每毫秒可执行的动作被切分成10000份

执行特点

  • 宏观:多个动作在一段时间内看似同时执行完毕(并发)
  • 微观:同一时刻只能处理一件事(串行)
  • 操作系统不断调度,动作A开始用某一分片,结束时可能用另一分片

二、同步与异步

2.1 同步方法(Sync)

特点

private void DoSomethingSync()
{
    // 线性执行,从上往下依次执行
    Console.WriteLine("步骤1");
    Thread.Sleep(1000);
    Console.WriteLine("步骤2");
    Thread.Sleep(1000);
    Console.WriteLine("步骤3");
}

优点

  • 符合人类思维逻辑,代码易读
  • 有序执行,结果可预测
  • 消耗计算机资源少

缺点

  • 执行慢,会卡顿界面
  • 只有一个线程(主线程/UI线程)参与计算
  • CPU忙碌时无暇处理其他任务

生活类比

  • 真心请人吃饭:Richard请Vn吃饭,Vn说还要忙一会儿,Richard说"那我等你,忙完一起去"

2.2 异步方法(Async)

特点

private void DoSomethingAsync()
{
    // 开启新线程执行
    Task.Run(() =>
    {
        Console.WriteLine("步骤1");
        Thread.Sleep(1000);
    });
    
    Task.Run(() =>
    {
        Console.WriteLine("步骤2");
        Thread.Sleep(1000);
    });
    
    // 主线程不等待,继续执行
    Console.WriteLine("主线程继续");
}

优点

  • 执行快,不卡顿界面
  • 多个线程并发执行
  • 提高程序响应能力

缺点

  • 无序执行,结果不可预测
  • 消耗更多计算机资源
  • 编程复杂度增加

生活类比

  • 客气请人吃饭:Richard客气地请Vn吃饭,Vn说还要忙一会儿,Richard说"那你先忙,我先去吃了"

核心理念

  • 以资源换时间:使用大量资源,降低时间成本

三、C#中的多线程实现

3.1 Thread(最原始)

Thread thread = new Thread(() =>
{
    Console.WriteLine("Thread执行");
});
thread.Start();
thread.IsBackground = true;  // 后台线程:进程结束,线程随之消失
thread.IsBackground = false; // 前台线程:进程结束,线程执行完才消失

3.2 ThreadPool(线程池)

  • 管理一组可重用的线程
  • 避免频繁创建和销毁线程的开销
// 将工作项加入线程池队列
ThreadPool.QueueUserWorkItem(state =>
{
    Console.WriteLine($"ThreadPool执行,线程ID: {Thread.CurrentThread.ManagedThreadId}");
});

// 带参数版本
ThreadPool.QueueUserWorkItem(state =>
{
    string msg = (string)state;
    Console.WriteLine($"参数: {msg}");
}, "hello");

⚠️ ThreadPool 无法精确控制线程,也不支持返回值和取消,实际开发中优先使用 Task。

3.3 Task(推荐使用)

Task的优势

  • .NET Framework 3.0时代实现
  • C#中多线程操作的最佳实现
  • 丰富的API,满足各种开发场景
  • Task操作的线程来自线程池

Task开启方式

// 方式1:new Task + Start
Task task = new Task(() =>
{
    Console.WriteLine("Task执行");
});
task.Start();

// 方式2:Task.Run(推荐)
Task.Run(() =>
{
    Console.WriteLine("Task执行");
});

// 方式3:TaskFactory
TaskFactory factory = new TaskFactory();
factory.StartNew(() =>
{
    Console.WriteLine("Task执行");
});

// 方式4:带返回值
Task<int> task = Task.Run(() =>
{
    return DateTime.Now.Year;
});

线程标识

// 通过线程ID确定是否为同一线程
int threadId = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"当前线程ID: {threadId:00}");

四、Task的核心方法

4.1 等待方法

Wait() - 单个任务等待

Task task = Task.Run(() =>
{
    Thread.Sleep(3000);
    Console.WriteLine("任务完成");
});

task.Wait(); // 主线程等待,会卡顿界面
task.Wait(1000); // 限时等待,过时不候
task.Wait(TimeSpan.FromMilliseconds(1100)); // 使用TimeSpan

WaitAll() - 等待所有任务

List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => DoWork1()));
tasks.Add(Task.Run(() => DoWork2()));
tasks.Add(Task.Run(() => DoWork3()));

Task.WaitAll(tasks.ToArray()); // 等待所有任务完成

WaitAny() - 等待任意一个任务

Task.WaitAny(tasks.ToArray()); // 任意一个任务完成即返回

4.2 回调方法(不阻塞)

ContinueWith() - 单个任务回调

Task task = Task.Run(() =>
{
    Thread.Sleep(3000);
    return "结果";
});

task.ContinueWith(t =>
{
    Console.WriteLine($"任务完成,结果:{t.Result}");
});

ContinueWhenAny() - 任意一个完成时回调

TaskFactory factory = new TaskFactory();
factory.ContinueWhenAny(tasks.ToArray(), completedTask =>
{
    Console.WriteLine("有一个任务完成了");
    // 不卡顿界面,用户体验好
});

ContinueWhenAll() - 所有完成时回调

factory.ContinueWhenAll(tasks.ToArray(), completedTasks =>
{
    Console.WriteLine("所有任务都完成了");
});

4.3 Delay() - 延迟执行

// Thread.Sleep - 阻塞主线程
Thread.Sleep(3000); // 主线程卡顿3秒

// Task.Delay - 不阻塞,配合ContinueWith使用
Task.Delay(3000).ContinueWith(t =>
{
    Console.WriteLine("3秒后执行");
    // 可能是新线程,也可能是主线程执行
});

五、应用场景

5.1 适合使用多线程的场景

场景1:多个独立任务并发执行

// 同时查询接口、缓存、数据库
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => QueryFromApi()));
tasks.Add(Task.Run(() => QueryFromCache()));
tasks.Add(Task.Run(() => QueryFromDatabase()));
Task.WaitAll(tasks.ToArray());

场景2:项目实战 - 多人协作开发

// 每个开发人员对应一个线程
TaskFactory factory = new TaskFactory();
List<Task> devTasks = new List<Task>();

devTasks.Add(factory.StartNew(() => Coding("张三", "权限模块")));
devTasks.Add(factory.StartNew(() => Coding("李四", "支付模块")));
devTasks.Add(factory.StartNew(() => Coding("王五", "订单模块")));

// 任意一人完成,准备环境
factory.ContinueWhenAny(devTasks.ToArray(), t =>
{
    Console.WriteLine("有人完成了,开始准备环境");
});

// 所有人完成,庆祝
factory.ContinueWhenAll(devTasks.ToArray(), t =>
{
    Console.WriteLine("所有人完成,一起吃饭庆祝");
});

5.2 实际业务场景

场景1:数据查询优先级

  • 同时查询缓存、数据库、第三方接口
  • 使用WaitAny,哪个先返回数据就用哪个
  • 其他线程自动放弃

场景2:首页数据加载

  • 首页包含:考勤信息、年度Top10、季度Top10、公告、通知
  • 每个模块开启一个线程并发查询
  • 使用WaitAll等待所有数据,组装后返回前端
  • 提高查询性能

5.3 不适合使用多线程的场景

  • 单个数据库查询(只有一个动作)
  • 简单的顺序操作
  • 需要严格顺序的业务逻辑

六、父子线程

Task parentTask = new Task(() =>
{
    Console.WriteLine("父线程开始");
    
    Task childTask1 = new Task(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine("子线程1");
    });
    
    Task childTask2 = new Task(() =>
    {
        Thread.Sleep(1000);
        Console.WriteLine("子线程2");
    });
    
    childTask1.Start();
    childTask2.Start();
    
    // 如果不等待子线程,父线程可能先结束
    // childTask1.Wait();
    // childTask2.Wait();
    
    Console.WriteLine("父线程结束");
});

parentTask.Start();
parentTask.Wait(); // 主线程等待父线程

注意事项

  • 父线程等待时,子线程可能还未执行完
  • 需要在父线程中显式等待子线程
  • 否则父线程结束,子线程内容可能未执行完

七、实用技巧

7.1 线程ID格式化

// 格式化为两位数,方便查看
string threadId = Thread.CurrentThread.ManagedThreadId.ToString("00");
Console.WriteLine($"线程ID: {threadId}");

7.2 时间戳格式化

string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
Console.WriteLine($"时间: {timestamp}");

7.3 性能测试

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

// 执行任务
DoSomething();

stopwatch.Stop();
Console.WriteLine($"耗时: {stopwatch.ElapsedMilliseconds}ms");

八、小结

  • 同步方法:有序、慢、阻塞、资源消耗少
  • 异步方法:无序、快、不阻塞、资源消耗多
  • Task 是首选:功能强大、API 丰富、来自线程池
  • Wait 系列:阻塞主线程,会卡顿界面
  • Continue 系列:不阻塞,用户体验好
  • 合理使用多线程:并发场景才使用,不要滥用
微波射频学习笔记18-------偶极子天线和微波天线设计介绍 几种天线设计方法的介绍 一、偶极子天线 1.天线模型 两根紧挨着的金属导体,长度均为四分之一波长,直径均远小于波长,两导体间距也远小于波长。 2.天线性能的设计因素 ① 单个导体长度L:(光速/频率)/4=四分之一波长(在空气中传播的波长),但在导体中传播,波长会变短; ② 导体半径R:远小于波长即可,使用导电率高些的材料,市面上常见直径零点几毫米就挺好,或者用波长/200,得出一个小200的值,也算远小于波长; ③ 两导体间距S:远小于波长即可,可以比半径更小点。 以上三个变量L、R、S,均可在仿真软件 阅读详情

相关推荐

蓝桥杯算法:打印图形——六芒星

【输入格式】 输入一行包含一个整数 n。 【输出格式】 输出一个六芒星,表示满足题意的图形。 【样例输入】 3 4 【样例输出】 【评测用例规模与约定】 对于所有评测用例,1 ≤ n ≤ 20。 总结: 第一次做图形题,做了蛮久,图形题有很多的方式去完成,它考验的是你能不能找到更简单的那一种方式. 我初看到这个图形,第一种想法是把这个六芒星当做六个小三角形来做,然后以某种规则排列一下,就能做出来,但是尝试了一下感觉太麻烦了。 然后我的第二种想法是,这个图形是对称图形,怎么能写出一半吗? 这样另一半想办

KeepCodeing 3835

个人C#面试题系列-更新至2022/09

C#面试题系列,单独记录一下毕业后这两年所经历的一些关于C#的面试。就当梳理一下知识。

lilizys的博客 1万+

影刀rpa的使用一--读取excel表格数据并循环出每一项

1、全部展示2、运行结果展示之后可以按照各自的需求对excel中取出的数据进行处理。

qq_69268437的博客 1万+

09-C#

⚠️ ThreadPool 无法精确控制线程,也不支持返回值和取消,实际开发中优先使用 Task。

噢~ 363

RFID射频识别技术介绍及简单应用

简单介绍RFID技术及其简单应用,后附简单门禁制作方法和代码

来者皆是客。 1万+

Synares病毒实战:如何从U盘感染中恢复你的Excel和EXE文件(附专杀工具推荐)

本文详细介绍了Synares感染型病毒的典型特征与传播机制,特别是其通过U盘感染Excel和EXE文件的行为。文章提供了一套从应急隔离、诊断到使用专杀工具进行深度清除与文件恢复的完整实战流程,并推荐了有效的安全软件和修复方法,旨在帮助用户最大程度救回重要数据并构建长效安全防护习惯。

weixin_29230649的博客 1808

C#数学计算包 Math.NET

1.Math.NET基本介绍 Math.NET官方网站:http://www.mathdotnet.com/ Math.NET的目标是为提供一款自身包含清晰框架的符号运算和数学运算/科学运算,它是C#开发的开源类库。Math.NET含了一个支持线性代数的解析器,分析复杂微分,解方程等等功能。这个项目大部分采用的是MIT/X11开源软件协议。目前该组件主要分为以下几个子项目,该组件同时也支持Mo...

Protear 1万+

yolov26改进 | Neck篇 | 利用Gold-YOLO改进yolov26对小目标检测能力(全网独家首发)

本文介绍利用Gold-YOLO的Neck改进YOLOv26,通过信息聚集—分发机制GD,先全局汇聚不同层级特征,再将融合后的全局信息重新注入各尺度分支,增强浅层细节与深层语义之间的交互,减少传统Neck逐层传递造成的信息损失。该结构虽然融合路径更长,但能够在不过度增加延迟的前提下提升多尺度目标检测能力,尤其适合大小目标并存、尺度变化明显和复杂背景场景。本文将讲解GD机制、Neck替换、模块注册与配置方法,并提供完整代码、配置文件及Codex修改思路,方便直接复现、实验对比和二次创新。

Snu77的博客 287

.net framework基础知识

目录 1.什么是.Net平台、.NET框架 2..NET版本 3.CLR(公共语言运行时) 4.BCL(基础类库) 5.FCL(框架类库) 3..NET的运行机制 6.为什么说.NET是平台无关的 7.术语 参考: 1.什么是.Net平台、.NET框架 “平台”(这里指软件技术平台,下面都指的是这个)就是能够独立运行并自主存在,为其所支撑的上层系统和应用提供运行所依赖的环境。...

chunchunlaila的博客 1585

【红外DDE算法】一种应用于高动态范围红外可视化的算法

【红外DDE算法】一种应用于高动态范围红外可视化的算法 - 这个算法背后的动机 - 展示这个算法的流程 - 然后讨论各个可调参数的意义。

sunwindl91181的博客 1680

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C#基础信息

C# 是一个现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的。C# 是由 Anders Hejlsberg 和他的团队在 .Net 框架开发期间开发的。C# 是专为公共语言基础结构(CLI)设计的。CLI 由可执行代码和运行时环境组成,允许在不同的计算机平台和体系结构上使用各种高级语言。下面列出了 C# 成为一种广泛应用的专业语言的原因:现代的、通用的编程语言。面向对象。面向组件。容易学习。结构化语言。

dwt123324的博客 680

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

.Net开发中的多线程编程-文章

微软.Net开发中的多线程编程文章,在www.webjx.com上搜索到的。http://www.webjx.com/search.php?type=title&keywords=%B6%E0%CF%DF%B3%CCVB.Net-C#多线程Thread-代理委托delegate编程 1、微软.Net开发中的多线程编程总结2007-10-152、Visual C#多线程参

VB.Net+Android.java 1619

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C#版本与.NET版本对应关系以及各版本的特性

C#版本与.NET版本对应关系以及各版本的特性及修改C#语言版本方法

hpx666的博客 4091

白骑士的C#教学基础篇 1.1 C#简介

C#(发音为 "C-Sharp")是微软开发的一种现代面向对象编程语言,专为.NET框架设计。它结合了C、C++和Java的特性,旨在提供简单、安全、高效的编程体验。C#支持面向对象编程、类型安全、高性能和跨平台应用。自2000年首次发布以来,C#经历了多个版本的演进,每个版本都带来了新的功能和改进,使其成为广泛应用于桌面、Web、移动和云端开发的重要语言。要开始使用C#开发,用户需要安装Visual Studio,并按照步骤进行配置和编程。

JeremyTC的博客 827

.NET 9 优化,抢先体验 C# 13 新特性

合集 - .NET 基础知识(3)1..NET 9 优化,抢先体验 C# 13 新特性08-202.《黑神话:悟空》神话再现,虚幻引擎与Unity/C#谁更强?08-213..NET 6.0 + WPF 使用 Prism 框架实现导航09-11收起阅读目录前言新特性总结下载地址参考链接最后 前言 微软即将在 2024年11月12日发布 .NET 9 的最终版本,而08月09日发布的.NET 9 P...

weixin_31346703的博客 702

c#多线程

一、基本概念 1、进程 首先打开任务管理器,查看当前运行的进程: 从任务管理器里面可以看到当前所有正在运行的进程。那么究竟什么是进程呢? 进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相...

weixin_43923285的博客 303

.NET周刊【9月第5期 2024-09-29】

如何在 Dequeue 期间将 System.Threading.Channels 应用于队列和处理分支。

InCerry的博客 2783

3 开源Math.NET基础数学类库使用C#解析Matlab的mat格式

前言   本人在09年使用该组件的时候,主要原因也是为了替代Matlab,进行相关数学计算,现在依然有很多人关注Matlab计算,特别是学生,而很多也在使用C#,所以这些人通常由于个人能力有限(无法精通某一个门语言来解决综合问题),无法单纯的通过C#或者Matlab来解决问题,就想通过混合编程来调用完成,其实本人也做过大量的Matlab.NET混合编程研究,而且也个人制作了一套视频教程,编写过很多文章,可以参考如下文章: 1.国内第一部Matlab和C#.Net混合编程入门级视频教程【完全免费】 2.

Prince的博客 1974

1 C# 入门基础,C#简介之什么是C#

这里是引用:w3cshool的C#教程 :链接地址:C#教程 C# 简介 由 xqjrorz 创建,Carrie 最后一次修改 2015-09-13 C# 简介 C# 是一个现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的。 C# 是由 Anders Hejlsberg 和他的团队在 .Net 框架开发期间开发的。 C# 是专为公共语...

忙碌的流氓兔 568

C#语言

C# 第一章:第一个C#程序 1.NET概述与C#应用 .NET是Microsoft.NET的简称,是基于Windows平台的一种技术。它包含了能在.NET Framework平台运行的所有编程语言。C#是一种全新的语言,在设计它的时候,微软博采众长,将C,C++,Java等多种开发语言的优点集于一身,它是专为.NET开发而设计的编程语言。 2 IDE环境 微软推出了强大的平台和技术...

wangboluo的博客 3704

C#/.NET这些实用的编程技巧你都会了吗?

专栏C#/.NET/.NET Core编程常用语法、算法、技巧、中间件、类库、工作业务实操练习集,配套详细的文章教程讲解,助你快速掌握C#/.NET/.NET Core中各种编程常用语法、算法、技巧、中间件、类库、工作业务实操等等。

专注于C#/.NET/.NET Core学习、工作、面试干货和实战教程分享。这里聚焦了大量的C#/.NET/.NET Core优质文章、开源项目、实用工具和学习、工作、面试心得。 1270

.NET周刊【9月第3期 2025-09-21】

文章探讨了 JSON 反序列化的重要性和实现方法。JSON 是现代编程中常用的数据格式,反序列化的过程涉及将网络格式转换为可读的格式。通过 C#代码,文章阐明了如何实现自定义的 JSON 解析器,包含各种数据类型和解析流程。解析过程如拆包裹,依次读取对象、数组、字符串等,最终将结构化数据呈现给用户。文章提供了一些代码示例,并强调了使用 MIT 协议开源的灵活性。整体而言,文章应用深刻,实用性强,清晰易懂,适合开发者学习。

InCerry的博客 1219

【原创】开源Math.NET基础数学类库使用(03)C#解析Matlab的mat格式

本博客所有文章分类的总目录:【总目录】本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:【目录】开源Math.NET基础数学类库使用总目录 前言   本人在09年使用该组件的时候,主要原因也是为了替代Matlab,进行相关数学计算,现在依然有很多人关注Matlab计算,特别是学生,而很多也在使用C#,所以这些人通常由于个人能力有限(无法精通某一个门语言来解决综合问题)

C#.NET与Matlab开发 696
上一篇: 08-C#.Net-Thread-学习笔记
下一篇: 10-C#.Net-多线程-进阶篇-学习笔记
似水明俊德
博客等级 码龄8年 247粉丝 276原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值