首页 > 编程语言 >【C#进阶】多线程和异步编程_2024-06-22

【C#进阶】多线程和异步编程_2024-06-22

时间:2024-06-22 22:09:44浏览次数:30  
标签:Task 06 进阶 await 线程 WriteLine Console 多线程

关于多线程和异步编程简单来说,就是多线程并行执行任务提速,异步编程等待不浪费资源,并发集合确保数据访问安全,三者合力提升程序效率与反应能力。

1. 理解线程

想象一下,你在厨房做饭,同时需要洗菜、切菜、炒菜。如果你一个人来做,就需要在这些任务之间来回切换,这很慢。但如果请几个朋友帮忙,每人负责一项任务,大家同时工作,效率就高多了。这里的“朋友”就像是计算机中的“线程”。

线程就是计算机程序中执行任务的最小单位。一个程序默认启动时只有一个主线程,但可以通过创建额外的线程来同时执行多个任务,这就是多线程

示例代码:

using System;
using System.Threading;

class MultiThreadingDemo
{
    static void Main()
    {
        // 这是主线程
        Console.WriteLine("主线程开始");
        
        // 创建并启动一个新的线程
        Thread thread = new Thread(DoWork);
        thread.Start();
        
        Console.WriteLine("主线程继续做其他事情");
        
        // 等待新线程完成(非必须,这里为了演示)
        thread.Join();
        
        Console.WriteLine("所有任务完成,主线程结束");
    }
    
    static void DoWork()
    {
        Console.WriteLine("新线程开始执行任务");
        Thread.Sleep(2000); // 模拟耗时操作
        Console.WriteLine("新线程任务完成");
    }
}

注释说明:这段代码中,Main方法所在的线程是主线程,它创建了一个新线程DoWork去执行一个耗时任务。Thread.Sleep(2000)模拟了这个耗时操作,让新线程暂停2秒,期间主线程可以继续执行其他任务。

2. Task和异步编程模型(async和await)

有时候,我们不希望直接管理线程,而是希望程序自动为我们处理并发问题。这时候,就可以使用.NET提供的Taskasync/await关键字。

想象你在等待外卖,你可以选择一直站在门口等(阻塞),也可以继续做其他事,听到门铃响再去拿(异步)。async/await就是让你的程序在等待某些耗时操作(如网络请求)时,可以去做别的事,不浪费时间。

示例代码:

using System;
using System.Threading.Tasks;

class AsyncDemo
{
    static async Task Main()
    {
        Console.WriteLine("开始下载文件");
        
        // 异步下载文件,不会阻塞主线程
        await DownloadFileAsync();
        
        Console.WriteLine("文件下载完成");
    }
    
    static async Task DownloadFileAsync()
    {
        // 模拟文件下载耗时操作
        await Task.Delay(2000);
        Console.WriteLine("文件下载中...");
    }
}

注释说明DownloadFileAsync方法模拟了文件下载,使用Task.Delay(2000)模拟耗时操作。await关键字让调用它的方法(这里是Main方法)在等待时可以“放手”,去做其他事情,直到DownloadFileAsync完成才继续往下执行。

3. 并发集合和线程安全

当你在多线程环境下访问和修改共享数据时,可能会遇到数据不一致的问题,这叫做“竞态条件”。为了解决这个问题,.NET提供了线程安全的集合,比如ConcurrentDictionary

想象你和朋友同时编辑一份购物清单,如果不小心同时添加了同样的物品,就会出错。线程安全的集合就像每个人都有自己的笔,在写之前先确认没人同时写,保证清单的正确性。

示例代码:

using System.Collections.Concurrent;
using System.Threading.Tasks;

class ThreadSafeCollectionsDemo
{
    static ConcurrentDictionary<string, int> shoppingList = new ConcurrentDictionary<string, int>();

    static async Task AddItemAsync(string item)
    {
        // 尝试添加或更新数量,线程安全
        shoppingList.AddOrUpdate(item, 1, (key, oldValue) => oldValue + 1);
        await Task.Yield(); // 模拟一点点耗时,让并发效果更明显
    }

    static async Task Main()
    {
        var tasks = new Task[10];
        
        for (int i = 0; i < 10; i++)
        {
            tasks[i] = AddItemAsync("苹果");
        }
        
        await Task.WhenAll(tasks);
        
        foreach (var item in shoppingList)
        {
            Console.WriteLine($"{item.Key}: {item.Value}");
        }
    }
}

注释说明:这段代码展示了如何使用ConcurrentDictionary来安全地在多线程环境下添加购物清单项。即使多个线程同时尝试添加“苹果”,AddOrUpdate方法也会确保不会有重复计数的问题。

总结:

  1. 多线程入门:线程是程序执行任务的基本单位,多线程允许程序同时执行多个任务,如同厨房里多位厨师同时准备不同菜肴,显著提升工作效率。通过创建和管理线程,你能使程序运行更加流畅,响应更快。

  2. 异步编程与Taskasyncawait关键字是C#中异步编程的核心,它们使程序能在等待耗时操作(如网络请求、磁盘I/O)时释放当前线程去做其他工作,如同等待外卖时可以继续做家务,不白白浪费时间,从而优化程序的整体性能。

  3. 并发集合与线程安全:在多线程环境中,直接访问共享数据可能导致数据不一致性问题。ConcurrentDictionary等并发集合为此而生,它们内置同步机制,确保了多线程访问时的数据安全,有效避免了竞态条件,让数据操作既高效又可靠。

这些知识点相互支撑,构成了处理并发问题、提升程序效率与稳定性的坚实基础。掌握它们,你就能在编写高质量、高性能应用程序的道路上迈出重要一步。

标签:Task,06,进阶,await,线程,WriteLine,Console,多线程
From: https://www.cnblogs.com/Jason54/p/18262801

相关文章

  • 2024-06-22:用go语言,给定一个起始下标为 0 的长度为3的整数数组 nums,根据这些数字构建
    2024-06-22:用go语言,给定一个起始下标为0的长度为3的整数数组nums,根据这些数字构建三角形。如果无法构成三角形,则返回"none";否则根据三角形的边长关系返回对应类型的字符串:equilateral(等边三角形)、isosceles(等腰三角形)或scalene(不等边三角形)。输入:nums=[3,3,3]。输出:"e......
  • 【办公类-50-01】20240620自主游戏观察记录表19周内容打乱
    背景需求:又到了期末,各种班级资料需要提交。有一份自主游戏观察记录需要写19周(每周2次)的观察记录,并根据参考书填写一级、三级、五级的评价指标。去年中六班的时候,我很认真的手写了21周的户外游戏活动内容,主动成为2个需要提交文本资料的班级。今年组长选了中二和中五提交......
  • 学习Ange记录--06~10
    06.changesymbolicinheap再来复习一下流程1.建立项目p=angr.Project(path)2.设置入口state=p.factory.blank_state(0xffffffff)3.设置符号对象pw=claripy.BVS('pw',64)4.这次是把符号放到堆上,于是可以自己创个新的堆就好了(1).给新的堆一个地址(2).给新的指向堆的指针一......
  • YC307A [ 20240622 CQYC省选模拟赛 T1 ] 划船(boat)
    题意给定一个有向图\(G\),以及将所有边反向重连的无向图\(T\)。你最多可以在\(T\)上连续走\(k\)条边,走过每条边的代价都为\(1\),然后必须在\(G\)的对应点上走一条边以恢复体力。若当前对应点没有出边,则停留在该点\(1\)代价。求每个点到\(n\)的最小代价。Sol考......
  • 2024.06.22【读书笔记】丨生物信息学与功能基因组学(第十七章 人类基因组 第一部分)【AI
    第一部分:人类基因组概述与测序历史(详细版)摘要:第十七章深入探讨了人类基因组的复杂性、测序历程以及其对现代科学的意义。人类基因组由约30,000至40,000个蛋白质编码基因组成,这些基因的表达和变异构成了我们生物学特征和疾病倾向的基础。本章节详细回顾了人类基因组计划的......
  • Zookeeper-06
    Zookeeper的java客户端   Zookeeper的Java客户端主要有以下几种:ZooKeeperJavaClient:这是官方提供的Java客户端,包含在ZooKeeper的发布版本中。它提供了一组简单的API,用于连接ZooKeeper服务器,并对节点进行操作。Curator:Curator是Netflix公司开发的一......
  • kedaOJ#P0609. 质因分解加强版
    题目P0609.质因分解加强版思路代码#include<iostream>#include<vector>#include<string>std::stringprimeFactorization(intn){std::vector<int>factors;std::vector<int>counts;for(inti=2;i*i<=n;++i)......
  • [AI资讯·0622] Claude3.5超越GPT-4o,360推出AI搜索,OpenAI收购Rockset,华为发布大模型
    AI资讯「网红」周鸿祎,要为AI带货突发!OpenAI收购数据公司盘古5.0重磅发布!华为云大模型年度杀招来了,人形机器人现场整活GPT-4o一夜被赶超!Anthropic推出Claude3.5,网友3分钟克隆马里奥游戏中国人自己的操作系统!余承东掏出纯血鸿蒙,华为AI大招硬刚苹果Claude3.5突然发布!GPT-4o......
  • 20240622训练
    文件名是abcd的逆天考试(算术(a)题面:给定一个长度为\(n\)的整数数列\(a_1,\dots,a_n\),求有多少个有序对\((i,j)\)满足\(i<j\wedgea_ia_j<a_i+a_j\)题解:枚举\(j\),有\(a_i(a_j-1)<a_j\),对\(a_j\)分类讨论。当\(a_j>1\),\(a_i<a_j/(a_j-1)\),即\(a_i\le1\)。当\(a_j=1\),\(0......
  • java多线程编程问题以及解决办法
    java多线程编程问题以及解决办法  多线程编程虽然可以提高程序的性能和响应速度,但也带来了许多复杂的问题,如竞态条件、死锁、线程安全问题、内存一致性错误等。常用的解决方法包括使用同步机制(如synchronized和ReentrantLock)、线程池、volatile关键字、以及合适的线程间......