.net 高并发(二,多线程)
一,
多线程可以通过System.Threading.Thread类来实现。下面是一个简单的示例,展示如何使用Thread类创建和管理多个线程:
| using System; | |
| using System.Threading; | |
| class Program | |
| { | |
| static void Main() | |
| { | |
| // 创建两个线程 | |
| Thread thread1 = new Thread(DoWork); | |
| Thread thread2 = new Thread(DoWork); | |
| // 启动线程 | |
| thread1.Start(); | |
| thread2.Start(); | |
| // 等待所有线程执行完毕 | |
| thread1.Join(); | |
| thread2.Join(); | |
| Console.WriteLine("所有线程执行完毕。"); | |
| } | |
| static void DoWork() | |
| { | |
| // 模拟线程执行的任务 | |
| for (int i = 0; i < 5; i++) | |
| { | |
| Console.WriteLine("线程 {0} 正在执行,当前索引值 {1}", Thread.CurrentThread.Name, i); | |
| Thread.Sleep(1000); // 模拟耗时操作 | |
| } | |
| } | |
| } |
在上面的示例中,我们创建了两个线程thread1和thread2,并使用Start()方法启动它们。每个线程都执行DoWork()方法,该方法模拟了线程要执行的任务。通过调用Join()方法,主线程会等待其他线程执行完毕后再继续执行。最后,程序输出“所有线程执行完毕”。
请注意,多线程编程需要特别小心,因为多个线程可能同时访问共享资源,导致数据竞争和不一致的问题。因此,需要使用适当的同步机制(如锁、互斥量、信号量等)来保护共享资源,并确保线程安全地访问它们。
二,
ThreadPool类提供了一种用于管理和调度线程池中线程的方法。使用线程池可以减少创建和销毁线程的开销,并提高应用程序的性能。
下面是一个使用ThreadPool的简单示例:
| using System; | |
| using System.Threading; | |
| class Program | |
| { | |
| static void Main() | |
| { | |
| // 提交任务到线程池 | |
| ThreadPool.QueueUserWorkItem(DoWork); | |
| // 等待所有任务执行完毕 | |
| ThreadPool.JoinAll(); | |
| Console.WriteLine("所有任务执行完毕。"); | |
| } | |
| static void DoWork(object state) | |
| { | |
| // 模拟线程执行的任务 | |
| for (int i = 0; i < 5; i++) | |
| { | |
| Console.WriteLine("线程池中的线程正在执行,当前索引值 {0}", i); | |
| Thread.Sleep(1000); // 模拟耗时操作 | |
| } | |
| } | |
| } |
在上面的示例中,我们使用ThreadPool.QueueUserWorkItem()方法将一个委托(这里是DoWork方法)提交到线程池中。该方法会异步执行,不会阻塞主线程。然后,通过调用ThreadPool.JoinAll()方法等待所有任务执行完毕。
与直接创建Thread对象相比,使用ThreadPool可以更高效地管理线程,因为线程池会根据需要自动调整线程的数量,并在不再需要时释放线程。此外,通过使用ThreadPool可以减少应用程序启动时创建的线程数量,从而减少资源消耗。
三,
Task类是System.Threading.Tasks命名空间下的一个重要类,它代表一个异步操作。使用Task可以简化多线程编程,并提供更好的控制和灵活性。
下面是一个使用Task的简单示例:
| using System; | |
| using System.Threading.Tasks; | |
| class Program | |
| { | |
| static void Main() | |
| { | |
| // 创建并启动Task | |
| Task task1 = Task.Run(() => DoWork()); | |
| task1.Wait(); // 等待Task完成 | |
| Console.WriteLine("任务1执行完毕。"); | |
| } | |
| static void DoWork() | |
| { | |
| // 模拟异步任务的操作 | |
| for (int i = 0; i < 5; i++) | |
| { | |
| Console.WriteLine("Task正在执行,当前索引值 {0}", i); | |
| Task.Delay(1000).Wait(); // 模拟耗时操作 | |
| } | |
| } | |
| } |
在上面的示例中,我们使用Task.Run()方法创建一个新的Task实例,并传入一个委托(这里是DoWork方法)作为参数。通过调用task1.Wait()方法,主线程会等待task1执行完毕后再继续执行。在DoWork()方法中,我们模拟了异步任务的操作,并通过Task.Delay()方法来等待一段时间,模拟耗时操作。
使用Task比直接使用Thread更方便,因为Task提供了更好的异常处理、状态管理、任务间通信和任务依赖性等功能。此外,通过使用Task可以更容易地利用并行处理和异步编程的优势,提高应用程序的性能和响应能力。

浙公网安备 33010602011771号