多线程就是多个线程同时工作的过程,我们可以将线程看作是程序的执行路径,每个线程都定义了一个独特的控制流,用来完成特定的任务。如果您的应用程序涉及到复杂且耗时的操作,那么使用多线程来执行是非常有益的。使用多线程可以节省 CPU 资源,同时提高应用程序的执行效率,例如现代操作系统对并发编程的实现就用到了多线程。到目前为止我们编写的示例程序都是单线程的应用程序,这样的应用程序一次只能执行一个任务。

下面是一个知识点全面、功能完善的 C# 多线程示例程序,涵盖了多线程的基本使用方式,包括:

  • 使用 Thread 类创建和启动线程

  • 线程同步(锁机制)

  • 使用 lock 关键字防止竞态条件

  • 使用 ManualResetEvent 实现线程间通信

  • 使用 ThreadPool 提高资源利用率

  • 异步操作与回调函数

using System;
using System.Threading;

class Program
{
    // 共享资源
    private static int sharedCounter = 0;
    private static readonly object lockObject = new object(); // 用于线程同步
    private static ManualResetEventSlim mre = new ManualResetEventSlim(false); // 用于线程间通信

    static void Main(string[] args)
    {
        Console.WriteLine("主程序开始...");

        // 1. 创建多个线程并启动
        Thread thread1 = new Thread(IncrementCounter);
        Thread thread2 = new Thread(IncrementCounter);

        thread1.Name = "Thread-1";
        thread2.Name = "Thread-2";

        thread1.Start();
        thread2.Start();

        // 等待两个线程完成
        thread1.Join();
        thread2.Join();

        Console.WriteLine($"最终计数器值: {sharedCounter}");

        // 2. 使用 ThreadPool 执行任务
        Console.WriteLine("\n使用线程池执行任务...");
        for (int i = 0; i < 5; i++)
        {
            int taskId = i;
            ThreadPool.QueueUserWorkItem(state =>
            {
                Console.WriteLine($"线程池任务 {taskId} 正在由 {Thread.CurrentThread.ManagedThreadId} 执行");
                Thread.Sleep(500);
            });
        }

        // 等待所有线程池任务完成
        Thread.Sleep(3000);

        // 3. 使用 ManualResetEvent 进行线程通信
        Console.WriteLine("\n演示线程通信...");
        Thread signalThread = new Thread(SignalAfterDelay);
        signalThread.Start();

        Console.WriteLine("主线程等待信号...");
        mre.Wait(); // 主线程阻塞,直到 signalThread 发出信号
        Console.WriteLine("收到信号,继续执行主线程");

        // 4. 异步方法调用
        Console.WriteLine("\n演示异步方法调用...");
        IAsyncResult asyncResult = new AsyncOperation().BeginAsyncMethod(
            OnAsyncCompleted, "Hello from Async"
        );

        // 可以在此处执行其他操作
        Console.WriteLine("主线程继续做其他工作...");

        // 等待异步操作完成
        asyncResult.AsyncWaitHandle.WaitOne();
        Console.WriteLine("异步操作已结束");

        Console.WriteLine("主程序结束.");
    }

    // 增加共享计数器的方法(带锁)
    private static void IncrementCounter()
    {
        for (int i = 0; i < 1000; i++)
        {
            lock (lockObject) // 使用 lock 防止竞态条件
            {
                sharedCounter++;
            }
        }

        Console.WriteLine($"{Thread.CurrentThread.Name} 完成。");
    }

    // 模拟延迟后发送信号
    private static void SignalAfterDelay()
    {
        Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} 开始延时...");
        Thread.Sleep(2000);
        mre.Set(); // 发送信号
        Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} 已发出信号");
    }

    // 异步操作类
    public class AsyncOperation
    {
        public IAsyncResult BeginAsyncMethod(AsyncCallback callback, object state)
        {
            return new AsyncResult(callback, state);
        }

        public string EndAsyncMethod(IAsyncResult result)
        {
            return ((AsyncResult)result).EndInvoke();
        }
    }

    // 异步结果类
    public class AsyncResult : IAsyncResult
    {
        private readonly AsyncCallback callback;
        private readonly object state;
        private bool isCompleted;

        public AsyncResult(AsyncCallback callback, object state)
        {
            this.callback = callback;
            this.state = state;
            this.isCompleted = false;
            ThreadPool.QueueUserWorkItem(DoWork);
        }

        public void DoWork(object state)
        {
            Console.WriteLine($"异步方法正在由线程 {Thread.CurrentThread.ManagedThreadId} 执行");
            Thread.Sleep(1000); // 模拟耗时操作
            this.isCompleted = true;

            if (callback != null)
                callback(this);
        }

        public string EndInvoke()
        {
            return "异步操作结果返回";
        }

        #region IAsyncResult 成员
        public object AsyncState => state;
        public WaitHandle AsyncWaitHandle => new ManualResetEvent(isCompleted);
        public bool CompletedSynchronously => false;
        public bool IsCompleted => isCompleted;
        #endregion
    }

    // 异步回调方法
    private static void OnAsyncCompleted(IAsyncResult result)
    {
        AsyncOperation operation = new AsyncOperation();
        string resultStr = operation.EndAsyncMethod(result);
        Console.WriteLine($"异步回调结果: {resultStr}");
    }
}

输出结果:

主程序开始...
Thread-1 完成。
Thread-2 完成。
最终计数器值: 2000

使用线程池执行任务...
线程池任务 0 正在由 5 执行
线程池任务 1 正在由 6 执行
线程池任务 2 正在由 7 执行
线程池任务 3 正在由 8 执行
线程池任务 4 正在由 9 执行

演示线程通信...
线程 10 开始延时...
主线程等待信号...
线程 10 已发出信号
收到信号,继续执行主线程

演示异步方法调用...
主线程继续做其他工作...
异步方法正在由线程 11 执行
异步回调结果: 异步操作结果返回
异步操作已结束
主程序结束.

 知识点解析

  • 线程创建与启动:通过 Thread 类创建线程,并使用 Start() 启动。

  • 线程同步:使用 lock 关键字确保对共享资源的安全访问,避免竞态条件。

  • 线程池:使用 ThreadPool.QueueUserWorkItem 将任务提交给线程池,提高系统性能。

  • 线程通信:通过 ManualResetEvent 控制线程之间的同步与通知。

  • 异步编程模型(APM):使用 IAsyncResultBegin/End 方法实现异步操作,并提供回调支持。

更多推荐