代码改变世界

为什么要多线程,c#多线程编程有哪些实现方式,怎么中止线程

  钟铧若岩  阅读(8)  评论(0编辑  收藏  举报

为什么要使用多线程


在软件开发中使用多线程有诸多好处,以下是详细解释:

  • 提高程序性能:现代计算机通常配备多核处理器,单线程程序只能利用一个核心的计算资源,而多线程程序可以将不同的任务分配到多个核心上并行执行,充分发挥多核处理器的优势,从而显著提高程序的整体运行效率。例如,在数据处理应用中,一个线程负责读取数据,另一个线程负责对数据进行分析和计算,这样可以减少总的处理时间。
  • 增强响应性:对于有用户界面(UI)的应用程序,若有耗时的操作在主线程中执行,会导致界面卡顿,影响用户体验。通过使用多线程,将耗时操作放在子线程中执行,主线程可以继续响应用户的输入,保持界面的流畅性。比如,在文件下载程序中,下载操作可以在子线程中进行,主线程负责处理用户的点击、取消等操作。
  • 资源共享与并发处理:多线程可以共享进程的资源,如内存、文件句柄等,同时可以并发地对这些资源进行操作。在服务器端应用中,多个客户端的请求可以由不同的线程来处理,提高服务器的并发处理能力,使得服务器能够同时服务更多的客户端。

C# 多线程编程的实现方式

1. 使用 Thread 类


Thread 类是 C# 中最基础的实现多线程的方式,它允许你创建和控制单个线程。
复制代码
using System;
using System.Threading;

class Program
{
    static void ThreadMethod()
    {
        Console.WriteLine("子线程开始执行");
        Thread.Sleep(2000); // 模拟耗时操作
        Console.WriteLine("子线程执行结束");
    }

    static void Main()
    {
        Thread newThread = new Thread(ThreadMethod);
        newThread.Start(); // 启动线程

        Console.WriteLine("主线程继续执行");
        newThread.Join(); // 等待子线程执行完毕
        Console.WriteLine("主线程执行结束");
    }
}
复制代码

在上述代码中,首先定义了一个 ThreadMethod 方法,该方法将在子线程中执行。然后创建了一个 Thread 对象,并将 ThreadMethod 作为参数传递给它,最后调用 Start 方法启动线程。

 

 

ParameterizedThreadStart 委托允许你创建一个可以接受单个对象类型参数的线程方法。下面是具体的示

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

class Program
{
    // 定义一个可以接受单个对象参数的方法
    static void ThreadMethod(object obj)
    {
        if (obj is string message)
        {
            Console.WriteLine($"线程接收到的消息: {message}");
        }
    }

    static void Main()
    {
        string data = "这是传递给线程的参数";
        // 创建一个 ParameterizedThreadStart 委托实例,指向 ThreadMethod 方法
        ParameterizedThreadStart start = new ParameterizedThreadStart(ThreadMethod);
        // 创建一个新的线程,并将委托实例传递给它
        Thread thread = new Thread(start);
        // 启动线程,并传递参数
        thread.Start(data);
        // 等待线程执行完成
        thread.Join();

        Console.WriteLine("主线程继续执行");
    }
}
复制代码

 

2. 使用线程池(ThreadPool

 

线程池可以管理和复用线程,减少线程创建和销毁的开销,提高性能。
 
复制代码
using System;
using System.Threading;

class Program
{
    static void ThreadPoolCallback(object state)
    {
        Console.WriteLine("线程池线程开始执行");
        Thread.Sleep(2000); // 模拟耗时操作
        Console.WriteLine("线程池线程执行结束");
    }

    static void Main()
    {
        ThreadPool.QueueUserWorkItem(ThreadPoolCallback);
        Console.WriteLine("主线程继续执行");
        Thread.Sleep(3000); // 等待线程池线程执行完毕
        Console.WriteLine("主线程执行结束");
    }
}
复制代码

这里使用 ThreadPool.QueueUserWorkItem 方法将一个工作项(即 ThreadPoolCallback 方法)加入到线程池的工作队列中,线程池会自动分配一个线程来执行该工作项。

3. 使用 Task 类

 

Task 类是 .NET 4.0 引入的用于异步编程的高级抽象,它基于线程池实现,提供了更简洁和强大的异步编程模型。
复制代码
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Task task = Task.Run(() =>
        {
            Console.WriteLine("任务开始执行");
            Thread.Sleep(2000); // 模拟耗时操作
            Console.WriteLine("任务执行结束");
        });

        Console.WriteLine("主线程继续执行");
        await task; // 等待任务执行完毕
        Console.WriteLine("主线程执行结束");
    }
}
复制代码
通过 Task.Run 方法可以创建并启动一个新的任务,该任务会在后台线程中执行。使用 await 关键字可以异步等待任务完成。

4. 使用 async/await 关键字

 

async/await 是 C# 中用于简化异步编程的语法糖,它建立在 Task 的基础之上。
复制代码
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        await DoWorkAsync();
        Console.WriteLine("主线程执行结束");
    }

    static async Task DoWorkAsync()
    {
        Console.WriteLine("异步方法开始执行");
        await Task.Delay(2000); // 模拟耗时操作
        Console.WriteLine("异步方法执行结束");
    }
}
复制代码

 

中止 C# 线程的方法

1. 使用标志位


通过定义一个布尔类型的标志位,在子线程中定期检查该标志位的值,当标志位为 true 时,线程自行退出
复制代码
using System;
using System.Threading;

class Program
{
    private static volatile bool isStopped = false;

    static void ThreadMethod()
    {
        while (!isStopped)
        {
            Console.WriteLine("子线程正在执行");
            Thread.Sleep(1000);
        }
        Console.WriteLine("子线程已停止");
    }

    static void Main()
    {
        Thread newThread = new Thread(ThreadMethod);
        newThread.Start();

        Thread.Sleep(3000); // 主线程等待一段时间
        isStopped = true; // 设置标志位为 true,通知子线程停止
        newThread.Join(); // 等待子线程退出
        Console.WriteLine("主线程执行结束");
    }
}
复制代码
这里使用 volatile 关键字确保 isStopped 变量在多线程环境下的可见性。

2. 使用 CancellationToken(适用于 Task

 

CancellationToken 是一种用于取消异步操作的机制,通常与 Task 结合使用。
 
复制代码
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        Task task = DoWorkAsync(cts.Token);

        await Task.Delay(3000); // 主线程等待一段时间
        cts.Cancel(); // 取消任务

        try
        {
            await task;
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("任务已取消");
        }

        Console.WriteLine("主线程执行结束");
    }

    static async Task DoWorkAsync(CancellationToken token)
    {
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine("任务正在执行");
            await Task.Delay(1000, token);
        }
        token.ThrowIfCancellationRequested();
    }
}
复制代码

 

在上述代码中,CancellationTokenSource 用于创建一个 CancellationToken,并通过 Cancel 方法请求取消任务。在 DoWorkAsync 方法中,定期检查 token.IsCancellationRequested 的值,当收到取消请求时,任务会抛出 OperationCanceledException 异常。

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示