zoukankan      html  css  js  c++  java
  • C#异步编程的实现方式——ThreadPool线程池

    在需要创建的线程很多,且都是比较小的线程的情况下,可以使用线程池(ThreadPool类)。ThreadPool是一个静态方法,提供了对一个线程集合的操作,它会在线程数不足时增加线程,空闲线程数过多时释放资源。

    1、ThreadPool简单应用

    调用ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallBack委托类型的方法,并把这个方分配给线程池中的线程。线程池是自动运行的,如果线程池还没有运行,就会创建一个线程池,并启动第一个线程。如果线程池己经在运行,且有一个空闲线程来完成该任务,就把该作业传递给这个线程。

    实例1:

    下面这个方法是一个符合WaitCallBack委托的方法:

            static void WaitCallBackMethod(object param)
            {
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine(String.Format("Thread {0} is running", param));
                    Thread.Sleep(1000);
                }
            }

    然后在主线程里给线程池添加方法:

            static void Main(string[] args)
            {
                for (int i = 1; i <= 3; i++)
                {
                    ThreadPool.QueueUserWorkItem(WaitCallBackMethod, i);
                }
                Console.Read();
            }

    实例2:

        /// <summary>
        /// 开启5个线程
        /// </summary>
        static void TestOne()
        {
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem((o) =>
                {
                    for (int j = 0; j < 3; j++)
                    {
                        Console.WriteLine("Thread {0} is runing.",o);
                        Thread.Sleep(1000);
                    }
                }, i);
            }
        }

    QueueUserWorkItem()方法的第二个参数是个object类型的参数,可传入一个数据到线程中。在主线程中,传入了3个方法到线程池中。运行结果如下:

    image

    可以看见三个线程分别在行动。顺序不一样是因为操作系统调度的原因。

    2、最大与最小线程数

    ThreadPool类会在需要时增减池中线程的线程数,直到最大的线程数。池中的最大线程数是可配置的。在双核CPU中,默认设置为1023个工作线程和1000个I/O线程。也可以指定在创建线程池时应立即启动的最小线程数,以及线程池,中可用的最大线程数。如果有更多的作业要处理,线程池中线程的个数也到了极限,最新的作业就要排队,且必须等待线程完成其任务。

    可用下面的方法查看:

    int workerThreads;
    int ioThreads;
    
    ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
    Console.WriteLine(String.Format("Max worker threads: {0};    Max I/O threads: {1}", workerThreads, ioThreads));
    
    ThreadPool.GetMinThreads(out workerThreads, out ioThreads);
    Console.WriteLine(String.Format("Min worker threads: {0};    Min I/O threads: {1}", workerThreads, ioThreads));

    结果为:

    image

    3、线程池的限制

    • 线程池中的所有线程都是后台线程。如果进程的所有前台线程都结束了,所有的后台线程就会停止。不能把入池的线程改为前台线程。
    • 不能给入池的线程设置优先级或名称。
    • 对于COM对象,入池的所有线程都是多线程单元(Multithreaded Apartment,MTA)线程。许多COM对象都需要单线程单元(Multithreaded Apartment,MTA)线程。
    • 入池的线程只能用于时间较短的任务。如果线程要一直运行(如Word的拼写检查器线程),就应使用Thread类创建一个线程。

    更多:

    C# 线程同步之排它锁/Monitor监视器类

    C# lock关键词/lock语句块、线程锁

    C# 并行编程 之 并发集合 (.Net Framework 4.0)(转)

  • 相关阅读:
    AD用户移除所属组
    Mysql中文乱码问题完美解决方案
    将sqllite3数据库迁移到mysql
    检查远端服务器端口是否打开
    远程桌面卡
    不同平台的线程并发接口对比
    stm32之中断配置
    stm32之CMSIS标准、库目录、GPIO
    stm32 中断几个库函数实现过程分析
    Tree命令使用
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5069992.html
Copyright © 2011-2022 走看看