学懂C#编程:常用高级技术——学会C#多线程开发(一)

多线程基本概念

在C#中,多线程允许你同时执行多个代码路径。每个线程代表一个独立的执行流,操作系统可以在不同的处理器核心上并行执行这些线程,或者在单个核心上通过时间分片来模拟并行执行。

关键概念:
  • Thread:代表一个执行单元,可以独立运行代码。
  • ThreadStartParameterizedThreadStart:委托类型,用于定义线程开始执行时调用的方法。
  • Thread Pool:一组预先创建的线程,用于执行多个任务,以减少线程创建和销毁的开销。
  • MutexSemaphoreMonitorLock:同步机制,用于控制多个线程对共享资源的访问,防止数据损坏或竞态条件。
  • Task在.NET 4.0及以后版本中引入,提供更高级的抽象,支持异步编程和并行处理。

应用场景

多线程在以下场景中非常有用:

  1. 提高响应性:在用户界面应用程序中,可以使用后台线程执行耗时操作,保持UI的响应性。
  2. 提高性能:在服务器应用程序中,多线程可以充分利用多核处理器,提高处理请求的效率。
  3. 并行处理:对于可以分解为多个独立部分的任务,如图像处理、数据分析等,多线程可以显著提高处理速度。
  4. 异步操作:在网络编程或IO密集型任务中,使用多线程可以避免阻塞主线程,提高程序的吞吐量。

实例展示及解读

示例1:简单的多线程
cs 复制代码
using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread newThread = new Thread(new ThreadStart(Run));
        newThread.Start();

        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Main thread: Do some work.");
            Thread.Sleep(100); // 模拟工作
        }

        newThread.Join(); // 等待新线程结束
        Console.WriteLine("Main thread: New thread has ended.");
    }

    static void Run()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("New thread: Working...");
            Thread.Sleep(200); // 模拟工作
        }
    }
}

解读

  • ThreadStart 委托指向 Run 方法,该方法将在新线程中执行。
  • newThread.Start() 启动新线程。
  • newThread.Join() 使主线程等待新线程完成。

示例2:使用线程池

cs 复制代码
using System;
using System.Threading;

class Program
{
    static void Main()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(Process));

        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Main thread: Do some work.");
            Thread.Sleep(100); // 模拟工作
        }

        Thread.Sleep(2000); // 主线程等待足够长的时间,以便线程池线程完成工作
    }

    static void Process(object state)
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("ThreadPool thread: Processing...");
            Thread.Sleep(200); // 模拟工作
        }
    }
}

解读

  • ThreadPool.QueueUserWorkItemProcess 方法添加到线程池队列中,线程池会自动分配一个线程来执行该方法。
  • 线程池适用于执行短期的异步任务,可以减少线程创建和销毁的开销。
示例3:使用 Task
cs 复制代码
using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Task newTask = Task.Run(() =>
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Task: Working...");
                Task.Delay(200).Wait(); // 模拟工作
            }
        });

        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Main thread: Do some work.");
            Task.Delay(100).Wait(); // 模拟工作
        }

        newTask.Wait(); // 等待任务完成
    }
}

解读

  • Task.Run 启动一个新任务,该任务在后台线程中执行。
  • Task.DelayThread.Sleep 的异步版本,不会阻塞线程。
  • newTask.Wait() 等待任务完成,类似于 Thread.Join()

结论

C# 提供了多种多线程和并行编程的工具,包括 ThreadThreadPoolTask。选择合适的工具取决于任务的性质和应用程序的需求。多线程编程需要谨慎处理共享资源的同步问题,以避免竞态条件和死锁。随着.NET的发展,Taskasync/await 已经成为处理异步操作的首选方式,提供了更简洁和易于理解的代码结构。

相关推荐
后端小张几秒前
【JAVA 进阶】深入理解Sentinel:分布式系统的流量守卫者
java·开发语言·spring boot·后端·spring·spring cloud·sentinel
cheems95271 分钟前
[JavaEE] CAS 介绍
java·开发语言·java-ee
zore_c6 分钟前
【数据结构】栈——超详解!!!(包含栈的实现)
c语言·开发语言·数据结构·经验分享·笔记·算法·链表
lkbhua莱克瓦247 分钟前
IO练习——登入注册
java·开发语言·io流·java练习题
Reuuse8 分钟前
登录突然失效:Axios 拦截器判空、localStorage 脏数据与环境变量踩坑
开发语言·前端
月明长歌9 分钟前
【码道初阶】【Leetcode105&106】用遍历序列还原二叉树:前序+中序、后序+中序的统一套路与“先建哪边”的坑
java·开发语言·数据结构·算法·leetcode·二叉树
Oliver_LaVine16 分钟前
java后端实现全链路日志ID记录
java·开发语言·spring
木头软件19 分钟前
批量将 Word 文档重命名为其标题
开发语言·c#·word
fantasy5_519 分钟前
C++ 智能指针深度解析:原理、实现与实战避坑
java·开发语言·c++
ERROR:9920 分钟前
野路子:把海量文档一次性转换成多个PPT
开发语言·人工智能·c#