From f77c10f1d5ca7fdef163a7d52cf5f8fc828cee28 Mon Sep 17 00:00:00 2001 From: Kister Hakusan <2753888203@qq.com> Date: Thu, 23 Oct 2025 17:48:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0Lesson18?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- C#进阶/C#进阶.sln | 12 ++ C#进阶/Lesson18_多线程/Lesson18_多线程.csproj | 10 ++ C#进阶/Lesson18_多线程/Program.cs | 125 ++++++++++++++++++ .../Lesson18_多线程练习.csproj | 10 ++ C#进阶/Lesson18_多线程练习/Program.cs | 107 +++++++++++++++ 5 files changed, 264 insertions(+) create mode 100644 C#进阶/Lesson18_多线程/Lesson18_多线程.csproj create mode 100644 C#进阶/Lesson18_多线程/Program.cs create mode 100644 C#进阶/Lesson18_多线程练习/Lesson18_多线程练习.csproj create mode 100644 C#进阶/Lesson18_多线程练习/Program.cs diff --git a/C#进阶/C#进阶.sln b/C#进阶/C#进阶.sln index 8605ea8..a5b1c35 100644 --- a/C#进阶/C#进阶.sln +++ b/C#进阶/C#进阶.sln @@ -73,6 +73,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson17_协变逆变", "Le EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson17_协变逆变练习", "Lesson17_协变逆变练习\Lesson17_协变逆变练习.csproj", "{DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson18_多线程", "Lesson18_多线程\Lesson18_多线程.csproj", "{90769697-6F30-4BB0-A74E-3C3A9BDD8669}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson18_多线程练习", "Lesson18_多线程练习\Lesson18_多线程练习.csproj", "{D98DCA4D-7F46-4376-9BBF-F1343D058FF3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -219,6 +223,14 @@ Global {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Debug|Any CPU.Build.0 = Debug|Any CPU {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Release|Any CPU.ActiveCfg = Release|Any CPU {DDF7EBE2-4B8E-4B48-97BC-06EB4E55796A}.Release|Any CPU.Build.0 = Release|Any CPU + {90769697-6F30-4BB0-A74E-3C3A9BDD8669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90769697-6F30-4BB0-A74E-3C3A9BDD8669}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90769697-6F30-4BB0-A74E-3C3A9BDD8669}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90769697-6F30-4BB0-A74E-3C3A9BDD8669}.Release|Any CPU.Build.0 = Release|Any CPU + {D98DCA4D-7F46-4376-9BBF-F1343D058FF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D98DCA4D-7F46-4376-9BBF-F1343D058FF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D98DCA4D-7F46-4376-9BBF-F1343D058FF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D98DCA4D-7F46-4376-9BBF-F1343D058FF3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/C#进阶/Lesson18_多线程/Lesson18_多线程.csproj b/C#进阶/Lesson18_多线程/Lesson18_多线程.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/C#进阶/Lesson18_多线程/Lesson18_多线程.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/C#进阶/Lesson18_多线程/Program.cs b/C#进阶/Lesson18_多线程/Program.cs new file mode 100644 index 0000000..3991bf2 --- /dev/null +++ b/C#进阶/Lesson18_多线程/Program.cs @@ -0,0 +1,125 @@ +namespace Lesson18_多线程 +{ + internal class Program + { + static bool isRunning = true; + static object obj = new object(); + static void Main(string[] args) + { + #region 知识点一 了解线程前先了解进程 + // 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动 + // 是系统进行资源分配和调度的基本单位,是操作系统结构的基础 + // 说人话:打开一个应用程序就是在操作系统上开启了一个进程 + // 进程之间可以相互独立运行,互不干扰 + // 进程之间也可以相互访问、操作 + #endregion + + #region 知识点二 什么是线程 + // 操作系统能够进行运算调度的最小单位。 + // 它被包含在进程之中,是进程中的实际运作单位 + // 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程 + // 我们目前写的程序 都在主线程中 + + // 简单理解线程: + // 就是代码从上到下运行的一条 “管道” + #endregion + + #region 知识点三 什么是多线程 + //我们可以通过代码 开启新的线程 + //可以同时运行代码的多条“管道” + #endregion + + #region 知识点四 语法相关 + //线程类 Thread + //命名空间 System.Threading + //1.声明一个新的线程 + // 注意 线程执行的代码 需要封装到一个函数中 + // 新线程 将要执行的代码逻辑 被封装到了一个函数语句中 + Thread t = new Thread(NewThreadLogic); + + //2.启动线程 + //默认为前台线程,不受主线程影响,会一直运行 + t.Start(); + + //3.设置为后台线程 + //后台线程 会随着主线程的结束而结束 + t.IsBackground = true; + + //4.关闭释放一个线程 + //如果开启的线程不是死循环,是能够结束的,那么不用刻意去关闭,它会自动释放 + //如果是死循环线程,那么有两种方式可以关闭 + //4.1-死循环中设置一个开关变量 来控制循环结束 + + //Console.ReadKey();//卡一下t线程,让其保持运行 + //isRunning = false;//按下后结束t线程 + + Console.ReadKey();//卡一下主线程,按下后结束 + + ////4.2-通过线程提供的方法(注意在.NET Core及以后的版本中 不推荐使用该方法) + ////终止线程 不推荐使用该方法 可能会引发不可预知的问题 + //try + //{ + // t.Abort(); + // t = null; + //} + //catch + //{ + // Console.WriteLine("ERROR"); + //} + //t = null; + + //5.线程休眠 + //Thread.Sleep(1000);//让线程休眠一定时间,单位是毫秒 + //现在在主线程中休眠1秒钟 + + + #endregion + + #region 知识点五 线程之间共享数据 + //多个线程使用的内存时共享的,都属于该应用程序的内存空间 + //所以要注意 当多线程 同时操作同一片内存区域时 可能会引发数据冲突问题 + //可以通过加锁的形式避免问题 + + //lock + //当我们在做个线程中想要访问同样的类型数据时,可以使用lock关键字来锁定该数据 + //这样当一个线程在访问该数据时,其他线程就无法访问该数据,直到该线程访问完毕,释放锁 + //lock(引用类型的对象) + + + while (true) + { + lock(obj) + { + Console.SetCursorPosition(0, 0); + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("????????????"); + } + } + //注意:锁定的对象不能是值类型,必须是引用类型 + //而且锁也会影响性能,所以只锁定必要的代码段 + + #endregion + + #region 知识点六 多线程对于我们的意义 + //可以用多线程专门处理一些复杂耗时的逻辑 + //比如 寻路、网络通信等等 + #endregion + } + + static void NewThreadLogic() + { + + while (isRunning) + { + //Thread.Sleep(1000); + //Console.WriteLine("NewThreadLogic"); + lock (obj) + { + Console.SetCursorPosition(10, 5); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("※"); + } + } + } + } +} diff --git a/C#进阶/Lesson18_多线程练习/Lesson18_多线程练习.csproj b/C#进阶/Lesson18_多线程练习/Lesson18_多线程练习.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/C#进阶/Lesson18_多线程练习/Lesson18_多线程练习.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/C#进阶/Lesson18_多线程练习/Program.cs b/C#进阶/Lesson18_多线程练习/Program.cs new file mode 100644 index 0000000..5b11fe1 --- /dev/null +++ b/C#进阶/Lesson18_多线程练习/Program.cs @@ -0,0 +1,107 @@ +namespace Lesson18_多线程练习 +{ + enum E_Direction + { + Up, + Down, + Left, + Right + } + struct Position + { + public int X; + public int Y; + } + interface IDraw + { + public void Draw(); + } + class Snake : IDraw + { + public E_Direction Direction; + Position Position; + public Snake() + { + Position.X = 15; + Position.Y = 5; + Direction = E_Direction.Right; + } + + public void Move() + { + switch (this.Direction) + { + case E_Direction.Up: + Position.Y -= 1; + break; + case E_Direction.Down: + Position.Y += 1; + break; + case E_Direction.Left: + Position.X -= 2; + break; + case E_Direction.Right: + Position.X += 2; + break; + default: + break; + } + } + public void Draw() + { + Console.SetCursorPosition(Position.X, Position.Y); + Console.Write("■"); + } + public void Clean() + { + Console.SetCursorPosition(Position.X, Position.Y); + Console.Write(" "); + } + public void ChangeDirection(E_Direction direction) + { + this.Direction = direction; + } + } + class Program + { + static Snake snake; + static void Main(string[] args) + { + snake = new Snake(); + Console.CursorVisible = false; + Thread inputThread = new Thread(input); + inputThread.Start(); + while (true) + { + Thread.Sleep(500); + snake.Clean(); + snake.Move(); + snake.Draw(); + } + + } + static void input() + { + while (true) + { + switch(Console.ReadKey(true).Key) + { + case ConsoleKey.UpArrow: + snake.ChangeDirection(E_Direction.Up); + break; + case ConsoleKey.DownArrow: + snake.ChangeDirection(E_Direction.Down); + break; + case ConsoleKey.LeftArrow: + snake.ChangeDirection(E_Direction.Left); + break; + case ConsoleKey.RightArrow: + snake.ChangeDirection(E_Direction.Right); + break; + default: + break; + } + } + } + } +}