编辑
2025-10-13
C#
00

在 C# 的多线程编程中,线程可以分为前台线程(Foreground Thread)和后台线程(Background Thread)。这两种线程在创建、使用和资源管理方面有着各自的特点。本文将详细介绍前台线程和后台线程的特点、应用场景以及具体示例,帮助开发者更好地理解这两个概念。

前台线程的特点

  • 阻止应用程序退出:前台线程会阻止应用程序的退出,直到所有前台线程完成运行。也就是说,主线程会等待所有前台线程结束之后才能关闭。
  • 优先级和性能:前台线程通常拥有较高的优先级,适合执行重要且需要持久执行的操作。
  • 资源占用:前台线程在运行时占用更多的系统资源,适合用于确保执行任务的重要场合。

后台线程的特点

  • 不阻止应用程序退出:后台线程在没有前台线程运行时会自动终止,无论其是否完成。这使得后台线程适合于做一些不太重要的清理或监听工作。
  • 较低的优先级:后台线程的优先级通常较低,适合用于不需要长时间运行的任务或短期操作。
  • 资源管理:后台线程的资源管理更加灵活,系统会在应用程序退出时自动清理后台线程的资源。

创建前台线程和后台线程的基本语法

以下是创建前台线程和后台线程的基本用法示例:

创建前台线程

C#
using System.Threading; Thread foregroundThread = new Thread(new ThreadStart(SomeMethod)); // 创建前台线程 foregroundThread.Start(); // 启动线程
编辑
2025-10-13
C#
00

电源管理概述

Windows 电源管理是现代应用程序中非常重要的功能,它可以帮助开发者控制系统电源状态,优化应用程序的能耗和性能。在 C# 中,我们可以通过 Microsoft.Win32 命名空间和 System.Windows.Forms 中的相关类来实现电源管理功能。

电源状态管理

电源状态监控

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppPower { public class PowerStatusMonitor { /// <summary> /// 获取当前电池状态 /// </summary> public (float,string,int) MonitorBatteryStatus() { PowerStatus powerStatus = SystemInformation.PowerStatus; // 电池电量百分比 float batteryPercentage = powerStatus.BatteryLifePercent * 100; // 电池充电状态 string chargeStatus = powerStatus.BatteryChargeStatus.ToString(); // 剩余电池时间 int remainingMinutes = powerStatus.BatteryLifeRemaining; return (batteryPercentage, chargeStatus, remainingMinutes); } } }

image.png

编辑
2025-10-11
C#
00

在 C# 的多线程编程中,Task 类是处理异步操作的重要赋能,而 Task.WaitAll 方法则用于等待一组任务的完成。这在处理多个并行任务时非常有用,特别是在需要确保所有并发操作完成之前继续执行的场景中。本文将详细介绍 Task.WaitAll 的特点、用法,并提供多个示例以展示其应用。

这是个好玩意,以前thread中要同步这个费了事。

Task.WaitAll 的特点

  • 等待所有任务完成Task.WaitAll 方法接收一个任务数组,并阻塞当前线程,直到所有任务完成。
  • 简单易用:提供直接的方式来等待多个任务,可以通过简单的调用来确保所有任务都已完成。
  • 返回状态:如果所有任务完成,它会正常返回。如果任何任务引发异常,WaitAll 将会抛出相应的异常。
  • 适用于处理多个并行任务的结果:可以用在需要处理多个异步操作的结果时,方便地跟踪和管理任务的状态。

使用 Task.WaitAll 的基本语法

以下是 Task.WaitAll 的基本用法示例:

C#
using System.Threading.Tasks; Task[] tasks = new Task[3]; // 创建任务 Task.WaitAll(tasks); // 等待所有任务完成

示例:使用 Task.WaitAll 等待多个任务完成

以下示例展示了如何创建多个任务,并使用 Task.WaitAll 等待所有任务完成。

C#
using System; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { Task[] tasks = new Task[3]; // 创建并启动多个任务 for (int i = 0; i < tasks.Length; i++) { int taskId = i + 1; // 为任务分配ID tasks[i] = Task.Run(() => { int delay = new Random().Next(1000, 5000); // 随机延迟 Thread.Sleep(delay); // 模拟耗时操作 Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒"); }); } // 等待所有任务完成 Task.WaitAll(tasks); Console.WriteLine("所有任务已完成。"); } }

image.png

编辑
2025-10-11
C#
00

在现代 C# 多线程编程中,Task 类是处理异步操作的重要工具。Task.WaitAny 方法允许你等待多个 Task 之一完成,这在处理并行任务时非常有用。本文将详细介绍 Task.WaitAny 的特点、用法,并提供多个示例以展示其应用。

Task.WaitAny 的特点

  • 等待任意任务完成Task.WaitAny 可以接收一个任务数组,并在任一任务完成时立即返回。这在需要处理并行任务的场合提供灵活性。
  • 非阻塞等待:虽然这个方法等待一个或多个任务完成,但它能以非阻塞的方式执行其他操作,帮助提高应用的响应性。
  • 返回完成任务的索引:当某个任务完成时,Task.WaitAny 返回完成任务在任务数组中的索引。
  • 支持超时Task.WaitAny 可以设置超时参数,指定等待时间,超时后将返回超时状态。

使用 Task.WaitAny 的基本语法

以下是 Task.WaitAny 的基本用法示例:

C#
using System.Threading.Tasks; Task[] tasks = new Task[3]; // 创建任务 int completedTaskIndex = Task.WaitAny(tasks); // 等待任意任务完成

示例:使用 Task.WaitAny 等待任务完成

以下示例展示了如何创建多个任务,并使用 Task.WaitAny 等待其中一个完成。

C#
namespace AppWaitAny { internal class Program { static void Main(string[] args) { Task[] tasks = new Task[3]; // 创建并启动多个任务 for (int i = 0; i < tasks.Length; i++) { int taskId = i + 1; tasks[i] = Task.Run(() => { int delay = new Random().Next(1000, 5000); // 随机延迟 Thread.Sleep(delay); Console.WriteLine($"任务 {taskId} 完成,耗时 {delay} 毫秒"); }); } // 等待任意任务完成 int completedTaskIndex = Task.WaitAny(tasks); Console.WriteLine($"任务 {completedTaskIndex + 1} 已完成。"); // 等待其他任务完成 Task.WaitAll(tasks); Console.WriteLine("所有任务已完成。"); } } }

image.png

编辑
2025-10-11
C#
00

ReaderWriterLockSlim 是 .NET Framework 中用于管理对共享资源的访问的一种同步机制。与传统的锁机制(如 MonitorMutex)相比,ReaderWriterLockSlim 更加高效,特别是在读操作远多于写操作的场景中。本文将详细介绍 ReaderWriterLockSlim 的特点、用法,以及多个示例以展示其应用。

ReaderWriterLockSlim 的特点

  • 读写分离:允许多个线程同时读取共享资源,但在写入时会独占访问。因此,它特别适合读多写少的场景。
  • 高效性:在读操作频繁的情况下,性能显著优于传统的锁,因为多个读线程可以并行执行。
  • 加锁机制:提供独占锁(用于写操作)、共享锁(用于读操作)机制,并支持升级锁定。
  • 优雅的管理:提供 EnterReadLockEnterWriteLockExitReadLockExitWriteLock 方法来控制访问。

使用 ReaderWriterLockSlim 的基本语法

以下是 ReaderWriterLockSlim 的基本用法示例:

C#
using System.Threading; ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); // 读操作 rwLock.EnterReadLock(); // 读取共享资源 rwLock.ExitReadLock(); // 写操作 rwLock.EnterWriteLock(); // 写入共享资源 rwLock.ExitWriteLock();

3示例:使用 ReaderWriterLockSlim 实现线程安全的字典

以下示例展示了如何使用 ReaderWriterLockSlim 来实现一个线程安全的字典,支持多个线程同时读取,但是在写入时会进行独占访问。

C#
namespace AppReaderWriterLockSlim { internal class Program { private static ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); private static Dictionary<int, string> data = new Dictionary<int, string>(); static void Main(string[] args) { Thread[] writers = new Thread[3]; Thread[] readers = new Thread[5]; for (int i = 0; i < writers.Length; i++) { writers[i] = new Thread(Writer); writers[i].Start(i + 1); } for (int i = 0; i < readers.Length; i++) { readers[i] = new Thread(Reader); readers[i].Start(i + 1); } foreach (var writer in writers) { writer.Join(); } foreach (var reader in readers) { reader.Join(); } } static void Writer(object id) { for (int i = 0; i < 5; i++) { rwLock.EnterWriteLock(); try { int key = i + (int)id * 10; // 确保写入不同的键 data[key] = $"Writer {id} wrote {key}"; Console.WriteLine($"Writer {id} added key {key}"); } finally { rwLock.ExitWriteLock(); } Thread.Sleep(100); // 模拟延迟 } } static void Reader(object id) { for (int i = 0; i < 5; i++) { rwLock.EnterReadLock(); try { foreach (var kvp in data) { Console.WriteLine($"Reader {id} read: {kvp.Key} => {kvp.Value}"); } } finally { rwLock.ExitReadLock(); } Thread.Sleep(50); // 模拟延迟 } } } }

image.png