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

发布于:2024-06-30 ⋅ 阅读:(14) ⋅ 点赞:(0)

多线程基本概念

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

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

应用场景

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

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

实例展示及解读

示例1:简单的多线程
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:使用线程池

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.QueueUserWorkItem 将 Process 方法添加到线程池队列中,线程池会自动分配一个线程来执行该方法。
  • 线程池适用于执行短期的异步任务,可以减少线程创建和销毁的开销。
示例3:使用 Task
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.Delay 是 Thread.Sleep 的异步版本,不会阻塞线程。
  • newTask.Wait() 等待任务完成,类似于 Thread.Join()

结论

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