惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
O
OpenAI News
酷 壳 – CoolShell
酷 壳 – CoolShell
The GitHub Blog
The GitHub Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
W
WeLiveSecurity
Hacker News: Ask HN
Hacker News: Ask HN
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
D
Docker
F
Full Disclosure
AI
AI
罗磊的独立博客
博客园 - 【当耐特】
U
Unit 42
S
SegmentFault 最新的问题
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Palo Alto Networks Blog
博客园_首页
H
Help Net Security
量子位
月光博客
月光博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
F
Fortinet All Blogs
D
DataBreaches.Net
B
Blog RSS Feed
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
爱范儿
爱范儿
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
CERT Recently Published Vulnerability Notes
Martin Fowler
Martin Fowler
Blog — PlanetScale
Blog — PlanetScale
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Securelist

博客园 - HackerVirus

在window系统下搭建C/C++开发环境 C#中DataGridView处理大数据量的技巧分享 CSharp-MVVM框架 Prism的事件聚合器 Toggling Focus Assist mode in Win 10 Programmatically Windsurf:超越 Cursor 的下一代 AI 编辑器 编程辅助新选择:Devin与Cursor的性能对比评测 支持多语言、多商店的商城,.Net7 + EF7领域驱动设计架构 Mysql高可用架构方案 软件架构中的那些惯用手段 .Net轻量级的CMS开源项目 前后端分离的权限管理框架,前端采用 Vue 3 框架,后端采用 .NET 8、ORM 采用 EF 8 linux文件属性 Roslyn的源生成器 IHostedService 和 BackgroundService 区别 Uno Platform是一个基于C#开源、功能强大、灵活的跨平台开发框架,用于快速构建单一代码库原生移动、Web、桌面和嵌入式应用程序 使用HslCommunication类库读取Siemens PLC DATA 功能齐全的 WPF 自定义控件 Sprint Planning
多线程&线程池
HackerVirus · 2026-04-16 · via 博客园 - HackerVirus

在C#的开发过程中,多线程是绕不开的一道坎,今天我想从线程开始讲起,希望对初学者能略有所助。
首先讲线程,线程是操作系统执行的最小单位,一个进程可以包含多个线程。这里举个简单例子,如果一个应用打开那就是一个进程,如果这个应用只能显示图片,那显示图片就是一个线程,如果还能同时播放音乐,那就是另一个线程。(执行图片显和播放音乐可能不止需要一个线程的执行,这里仅为快速理解特意举例)。
诶,相信现在你明白为啥需要多线程了。首先就是我需要多线程来帮我同时做多件事情,毕竟电脑的CPU性能有空闲,如果多个任务能够同时跑就最好同时跑,提升效率;其次就是响应性,就如同日常使用电脑软件,你点击播放音乐,然后又去点击另一个页面去添加到播放列表。如果是单线程的话,那么在歌曲没播放完成前你的添加都会一直卡着,直到歌曲放完才能按照顺序去执行添加操作。好了,经过简单介绍我们也大致理解了多线程在日常开发中的作用是什么了,一个是并发性,一个是响应性。接下来我们学习如何使用多线程。
生产者-消费者模式
在正式讲解多线程之前,我们先简单介绍下生产者-消费者模式。这是一种软件设计模式,简单来说就是在软件开发中,加入有一个发送数据的类A,一个接收数据的类B,如果A发送数据过快,B接收不过来,那必然造成阻塞或者数据缺失;反之如果B接收过快,那就需要一直等着A发送,也不合理。所以在中间创建一个数据缓存队列,用来平衡并传输数据,这就是生产者消费者模式。举个简单例子,就像快递公司,站点和顾客一样,如果每个顾客都去公司领快递,一旦公司出货过慢,顾客就得一直等;如果过快,快递堆积,顾客有可能拿错。所以就需要一个站点,一个站点存2000个快递,顾客按号领取,一旦领取一个,快递公司就会收到通知,再补一个快递到达站点。这样就能保证了快递的收发平衡与准确率。这里推荐一篇文章:https://www.cnblogs.com/luego/p/12048857.html (只需要大致理解生产者消费者模式即可)
多线程的应用
好了,已经明了多线程的用途了,我们来看看如何使用?这里有关线程的用法总结推荐: https://www.cnblogs.com/wyt007/p/9486752.html
//这里我们简单搭个案例,在一个窗口上设置两个文本框,两个单独线程分别在对应文本框内循环打印数字
主窗口MainWindow.axmal

image

主窗口ViewModel MainWindow.axmal.cs代码:

点击查看代码

//创建两个线程与线程方法,并在命令方法内执行即可
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MultiThreading.ViewModels;

public partial class MainWindowViewModel : ObservableObject
{
    

以上就完成了,这就是多线程的应用,运行效果如下图:

夸克录屏_2026-01-17_08-52-47

可以看见线程一和线程二是同时执行且独立于UI线程的,也就是说两个文本框运行的同时,UI页面的按钮还可以进行点击,如果添加文本框在其上还可以在线程一二执行时编辑文本框。

线程池的引入
当然以上只是多线程的一个简单应用,随着c#的不断发展,为了便于多线程的使用(创建销毁线程,自行管理其生命流程是一件很麻烦的事,也容易出错),出现了更便于使用线程的方法,线程池就诞生了。接下来我们看看线程池的应用,依旧是上面的例子做扩展,逐步加深理解为什么要用线程池。先看要实现的运行效果如图:

夸克录屏_2026-01-30_10-25-58

//增加一个文本框执行线程三,真实开发中往往并发线程会更多

image

//对应的ViewModel业务层代码(增加了线程三及线程三任务)

点击查看代码

using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MultiThreading.ViewModels;

public partial class MainWindowViewModel : ObservableObject
{
    

从上看出,如果线程增加过多,创建线程,启动线程,销毁线程都是一件很重复性甚至麻烦易出错的事情,所以我们引入了线程池,只修改ViewModel层,应用如下:点击查看代码

using System;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MultiThreading.ViewModels;

public partial class MainWindowViewModel : ObservableObject
{
    [ObservableProperty] private string _thread1Txt = "线程一";
    [ObservableProperty] private string _thread2Txt = "线程二";
    [ObservableProperty] private string _thread3Txt = "线程三";
    
    

从以上实现可以看出,无论对于线程创建,还是线程的同步实现等,ThreadPool都有更简洁的实现方式。但是请注意,线程池的出现只是为了简化实现多且小的异步任务(毕竟为每个任务创建线程和管理线程实在十分吃力且占用内存),线程池也有劣势,譬如它只是个可复用线程队列(其实细细体会,它就是一种线程的生产者消费者模式的体现),无法对内部单个线程进行严格管理,Thread就不一样,可以设置优先级,生命流程也可以覆盖整个进程,更加自由。

Task,async和await的发展
不过以上ThreadPool的应用随着发展,佬们还是觉得很麻烦,所以更优的异步实现——增强版线程池它来了————Task&async,await相结合。直接看基于以上ThreadPool的Task&async/await实现例码:

点击查看代码

using System;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MultiThreading.ViewModels;

public partial class MainWindowViewModel : ObservableObject
{
    [ObservableProperty] private string _thread1Txt = "线程一";
    [ObservableProperty] private string _thread2Txt = "线程二";
    [ObservableProperty] private string _thread3Txt = "线程三";
    
    public void DoSomething()
    {
        for (int i = 0; i < 20; i++)
        {
            string work = i.ToString();
            Thread.Sleep(100);
                
            

由此可以看出,用Task&async/await实现更为优雅,同时也让代码可读性更强。这种异步实现是当前首选的现代方式。其本质还是与Thread是一样的,都是为了实现异步,但是减少了许多重复代码,可读性也更高,所以,其实多线程并没有多复杂,从Thread到ThreadPool再到Task,无非就是使得实现方式更便捷,根本的目的都是一样为实现并行任务。但是关于线程之间的死锁以及资源冲突等相关问题,都是我们在实际开发中需要避免,至于这一部分,我推荐一篇文章:https://www.cnblogs.com/willick/p/13967346.html ,希望能帮助您解决不惑。