当前位置: 首页 > article >正文

浅谈C#之线程创建和管理

一、基本介绍

        线程是一种并发执行的机制,允许程序同时执行多个任务。线程的使用使得我们能够利用计算机的多核处理器,实现程序的并行执行,提高系统的性能和响应能力。本文将详细介绍C#中线程的定义和使用方法,涵盖线程的创建、启动、同步和管理等方面。        

        线程管理是一个重要的概念,因为多线程编程可以帮助你提高应用程序的性能,特别是在执行耗时的操作时。

二、关键点

  1. 线程的创建与启动

    • 使用System.Threading.Thread类来创建线程。你可以通过继承Thread类并重写Run方法,或者直接传递一个委托给Thread类的构造函数来创建线程。
    • 通过调用Thread.Start()方法来启动线程。
  2. 线程的同步

    • 使用lock语句来同步对共享资源的访问,防止多个线程同时修改同一个资源。
    • Monitor类提供了更高级的同步功能,如等待、通知和超时。
  3. 线程池

    • 线程池是.NET Framework提供的一种机制,用于重用线程,减少创建和销毁线程的开销。
    • 通过ThreadPool.QueueUserWorkItem方法将任务提交到线程池。
  4. 线程的生命周期管理

    • 线程有几种状态,如运行、等待、阻塞、死亡等。
    • 可以使用Thread.Join()方法等待线程完成,或者使用Thread.Abort()方法强制终止线程(不推荐,因为它可能导致资源未正确释放)。
  5. 线程的优先级

    • 可以通过Thread.Priority属性设置线程的优先级,影响线程的调度顺序。
  6. 线程局部存储(Thread Local Storage, TLS)

    • 使用ThreadLocal<T>类可以为每个线程存储一个独立的值,这对于避免线程间的数据共享非常有用。
  7. 异步编程模型(APM)和任务并行库(TPL)

    • .NET Framework提供了异步编程模型,通过IAsyncResult接口和回调函数来实现异步操作。
    • .NET 4.0引入了任务并行库(TPL),它提供了Task类和Parallel类,使得异步编程更加简单和强大。
  8. CancellationToken

    • 用于在长时间运行的操作中提供取消机制,允许用户在操作完成前请求取消。
  9. 线程安全集合

    • .NET提供了一些线程安全的集合类,如ConcurrentDictionary,可以在多线程环境中安全地使用。
  10. 异常处理

    • 在多线程环境中,异常处理变得更加复杂,因为异常可能发生在不同的线程中。确保正确地捕获和处理线程中的异常。

三、示例代码

  创建和启动线程

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 创建线程
        Thread thread = new Thread(new ThreadStart(ThreadMethod));
        thread.Start(); // 启动线程

        // 等待线程完成
        thread.Join();
    }

    static void ThreadMethod()
    {
        Console.WriteLine("Thread running...");
    }
}

线程同步

using System;
using System.Threading;

class Program
{
    static object lockObject = new object();
    static int sharedResource = 0;

    static void Main()
    {
        Thread thread1 = new Thread(new ThreadStart(Increment));
        Thread thread2 = new Thread(new ThreadStart(Increment));

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

        thread1.Join();
        thread2.Join();

        Console.WriteLine($"Final value: {sharedResource}");
    }

    static void Increment()
    {
        for (int i = 0; i < 10000; i++)
        {
            lock (lockObject)
            {
                sharedResource++;
            }
        }
    }
}

使用线程池

using System;
using System.Threading;

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

        Console.WriteLine("Main thread continues to run while work items are processed.");
    }

    static void DoWork(object stateInfo)
    {
        Console.WriteLine("Work item starting...");
        Thread.Sleep(2000); // 模拟耗时操作
        Console.WriteLine("Work item finishing...");
    }
}

线程的生命周期管理

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread thread = new Thread(new ThreadStart(ThreadMethod));
        thread.Start();

        Console.WriteLine("Main thread waiting for thread to complete...");
        thread.Join(); // 等待线程完成
        Console.WriteLine("Thread has completed.");
    }

    static void ThreadMethod()
    {
        Console.WriteLine("Thread running...");
        Thread.Sleep(5000); // 模拟耗时操作
    }
}

线程优先级

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread thread = new Thread(new ThreadStart(ThreadMethod));
        thread.Priority = ThreadPriority.AboveNormal;
        thread.Start();
    }

    static void ThreadMethod()
    {
        Console.WriteLine("Thread running with priority: " + Thread.CurrentThread.Priority);
    }
}

线程局部存储

using System;
using System.Threading;

class Program
{
    static ThreadLocal<int> threadLocalValue = new ThreadLocal<int>(() => 0);

    static void Main()
    {
        Thread thread1 = new Thread(new ThreadStart(ThreadMethod));
        Thread thread2 = new Thread(new ThreadStart(ThreadMethod));

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

        thread1.Join();
        thread2.Join();
    }

    static void ThreadMethod()
    {
        threadLocalValue.Value++;
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} has value: {threadLocalValue.Value}");
    }
}

异步编程模型(APM)

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        AsyncResult result = new AsyncResult();
        result.BeginInvoke(DoWork, result);

        Console.WriteLine("Main thread continues to run...");
        result.AsyncWaitHandle.WaitOne(); // 等待异步操作完成

        Console.WriteLine("Work completed.");
    }

    static void DoWork(IAsyncResult ar)
    {
        AsyncResult result = (AsyncResult)ar;
        result.EndInvoke();
        Console.WriteLine("Work item completed.");
    }
}

public class AsyncResult : IAsyncResult
{
    public object AsyncState { get; private set; }
    public WaitHandle AsyncWaitHandle { get; private set; }

    public bool CompletedSynchronously => false;
    public bool IsCompleted { get; private set; }

    public AsyncResult()
    {
        AsyncState = null;
        AsyncWaitHandle = new ManualResetEvent(false);
    }

    public void BeginInvoke(Action callback, object state)
    {
        AsyncState = state;
        ThreadPool.QueueUserWorkItem(_ =>
        {
            DoWork();
            if (callback != null)
            {
                callback();
            }
            IsCompleted = true;
            AsyncWaitHandle.Set();
        });
    }

    public void EndInvoke()
    {
        AsyncWaitHandle.WaitOne();
    }

    private void DoWork()
    {
        Console.WriteLine("Work item starting...");
        Thread.Sleep(2000); // 模拟耗时操作
        Console.WriteLine("Work item finishing...");
    }
}

任务并行库(TPL)

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Task task1 = Task.Run(() => DoWork());
        Task task2 = Task.Run(() => DoWork());

        await Task.WhenAll(task1, task2);

        Console.WriteLine("Main thread continues to run while tasks are processed.");
    }

    static void DoWork()
    {
        Console.WriteLine("Task starting...");
        Thread.Sleep(2000); // 模拟耗时操作
        Console.WriteLine("Task finishing...");
    }
}

CancellationToken

using System;
using System.Threading;
using System.Threading.Tasks;

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

        Task task = Task.Run(() => DoWork(token), token);

        Console.WriteLine("Press any key to cancel the task...");
        Console.ReadKey();

        cts.Cancel();
        try
        {
            await task;
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Task was canceled.");
        }
    }

    static void DoWork(CancellationToken token)
    {
        for (int i = 0; i < 5; i++)
        {
            if (token.IsCancellationRequested)
            {
                Console.WriteLine("Task was canceled.");
                break;
            }
            Console.WriteLine($"Task is running... {i}");
            Thread.Sleep(1000);
        }
    }
}

线程安全集合

using System;
using System.Collections.Concurrent;
using System.Threading;

class Program
{
    static ConcurrentBag<int> concurrentBag = new ConcurrentBag<int>();

    static void Main()
    {
        Thread thread1 = new Thread(new ThreadStart(AddNumbers));
        Thread thread2 = new Thread(new ThreadStart(AddNumbers));

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

        thread1.Join();
        thread2.Join();

        Console.WriteLine($"Total numbers: {concurrentBag.Count}");
    }

    static void AddNumbers()
    {
        for (int i = 0; i < 10000; i++)
        {
            concurrentBag.Add(i);
        }
    }
}


http://www.kler.cn/a/302247.html

相关文章:

  • 【Linux】HTTP协议和HTTPS加密
  • 学习日志010--python异常处理机制与简单文件操作
  • 三周精通FastAPI:37 包含 WSGI - Flask,Django,Pyramid 以及其它
  • idea 弹窗 delete remote branch origin/develop-deploy
  • 性能测试|JMeter接口与性能测试项目
  • 软件工程概论项目(二),node.js的配置,npm的使用与vue的安装
  • 基于深度学习的多模态信息检索
  • MapBox Android版开发 4 国际化功能v11
  • 什么不建议通过 `Executors` 构建线程池?
  • 抓包工具检测手把手教学 - 某招聘网站
  • 7-6 列出连通集
  • pyqt自定义文本编辑器
  • TCP通信实现
  • 2024 天池云原生编程挑战赛决赛名单公布,9 月 20 日开启终极答辩
  • 【从0开始在CentOS 9中安装redis】
  • Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK
  • openVX加速-常见问题:适用场景、AI加速、安装方式等
  • 模板(C++)
  • Java中的List与Set转换
  • jantic/DeOldify部署(图片上色)附带Dockerfile和镜像
  • Linux下的系统接口(实时更新)
  • 人工智能安全治理框架导图
  • 【泰克生物】酵母单杂交技术在基因调控研究中的应用
  • 数据结构——查找算法
  • 240908-结合DBGPT与Ollama实现RAG本地知识检索增强
  • OpenCV结构分析与形状描述符(23)确定一个点是否位于多边形内的函数pointPolygonTest()的使用