C# 实现多线程的几种方式

81

在C#中,实现多线程编程有多种方式,每种方式适用于不同的场景

使用 Thread 类

命名空间: System.Threading

特点: 最基础的多线程方式,直接控制线程的创建和管理

示例:

public class Program
{
    public static void Main(string[] args)
    {
        // 不带参数的线程
        Thread threada = new Thread(new ThreadStart(PalnA));
        threada.Start();

        // 带参数的线程
        Thread threadb = new Thread(new ParameterizedThreadStart(PalnB));
        threadb.Start("ParameterizedThreadStart");

        Console.ReadKey();
    }

    public static void PalnA()
    {
        Console.WriteLine("ThreadStart");
    }

    public static void PalnB(object? param)
    {
        var message = param as string;
        Console.WriteLine(message);
    }
}

适用场景:

需要精细控制线程生命周期(如优先级、前台/后台线程)。

简单、少量的线程任务。

缺点:

频繁创建/销毁线程开销大,不适合高并发。

使用 ThredPool 类

命名空间: System.Threading

特点: 重用线程,减少创建/销毁开销,适合短任务。

public class Program
{
    public static void Main(string[] args)
    {
        // 使用ThredPool类
        ThreadPool.QueueUserWorkItem(PalnB);
        ThreadPool.QueueUserWorkItem(PalnB, "ThreadPool");

        Console.ReadKey();
    }

    public static void PalnB(object? param)
    {
        var message = param as string;
        Console.WriteLine(message);
    }
}

适用场景:

短时间完成的小任务(如文件I/O、网络请求)。

避免手动管理线程。

缺点:

无法控制线程优先级或直接获取返回值。

使用 Task.Run

命名空间: System.Threading.Tasks

特点: 基于线程池的高级抽象,支持异步操作、返回值和异常处理。

示例:

public class Program
{
    public static async Task Main(string[] args)
    {
        // 使用异步方法

        // 异步不等待
        Task.Run(PlanA);

        // 异步等待,不带返回值
        await Task.Run(PlanA);

        // 异步等待,带返回值
        bool result = await Task.Run<bool>(PlanB);

        // 阻塞直到结果返回
        var task = Task.Run(PlanB);
        // TO DO 其他事情
        // ....
        result = task.Result;

        Console.ReadKey();
    }

    public static async Task PlanA()
    {
        Console.WriteLine("Task不带返回值");
    }
    public static bool PlanB()
    {
        Console.WriteLine("Task带返回值");
        return true;
    }
}

适用场景:

异步编程(配合 async/await)。

需要任务链、延续或结果聚合(如 Task.ContinueWith)。

优点:

代码简洁,天然支持异步编程模型(APM)。

使用 Parallel 类 (数据并行)

命名空间: System.Threading.Tasks

特点: 自动并行化循环或任务,简化数据并行操作。

示例:

public class Program
{
    public static async Task Main(string[] args)
    {
        // 使用Parallel 类(数据并行)
        Parallel.For(0, 10, i => {
            Console.WriteLine($"Parallel.For iteration {i}");
        });

        Parallel.ForEach(new[] { "A", "B", "C" }, item => {
            Console.WriteLine($"Processing {item}");
        });
        Console.ReadKey();
    }
}

适用场景:

数据密集型并行计算(如矩阵运算、批量处理)。

替代传统 for/foreach 循环以提升性能。

注意:

需要避免共享资源的竞争条件。

适用场景:

I/O密集型操作(如文件读写、网络请求)。

需要保持UI线程响应的桌面/移动应用。

注意:async/await 本身不创建新线程,而是利用任务调度。

使用定时器

使用 System.Timers.Timer 或 System.Threading.Timer

特点: 定时触发任务,适合周期性操作。

示例:

System.Threading.Timer timer = new System.Threading.Timer(_ => {
    Console.WriteLine("Timer tick!");
}, null, 0, 1000); // 立即启动,每隔1秒触发

注意事项

线程安全:使用 lock、Monitor、Mutex 或并发集合(如 ConcurrentQueue)避免竞态条件。

资源释放:确保及时释放线程或任务占用的资源。