线程从陌生到熟悉

线程从陌生到熟悉

CL景逸SUV线程池并不会在CLCR-V伊始化时即时创造线程,而是在应用程序要开创线程来运营职责时,线程池才最早化三个线程。
线程池早先化时是还未有线程的,线程池里的线程的领头化与其余线程相像,然则在完毕任务之后,该线程不会自动销毁,而是以挂起的情景重返到线程池。直到应用程序再一次向线程池发出央浼时,线程池里挂起的线程就能够另行激活实践职责。
这般既省去了树立线程所变成的性质损耗,也能够让八个职分一再重用同一线程,进而在应用程序生存期内节约多量支出。

几近年来我们来谈谈线程池:

因此CL卡宴线程池所确立的线程总是默以为后台线程,优先级数为ThreadPriority.Normal。

应用程序可以有八个线程,那几个线程在蛰伏状态中须要开支大量日子来等待事件发生。别的线程或然步向睡眠状态,並且仅依期被唤醒以轮循修改或更新景况消息,然后再一次步入休眠状态。为了简化对那些线程的管住,.NET框架为每个进度提供了叁个线程池,叁个线程池有若干个等待操作情状,当两个守候操作完结时,线程池中的扶植线程会实施回调函数。线程池中的线程由系统管理,程序员无需费事于线程管理,能够三月不知肉味处理应用程序任务。通过底子类库中的ThreadPool类提供三个线程池,该线程池可用来发送专门的工作现,管理异步I/O,代表任何线程等待及处理定时器.ThreadPool类的具有办法都是静态方法.ThreadPool自个儿也是贰个静态类.
大家来会见他的概念和后生可畏都部队分常用的办法:
 public
static class ThreadPool
{
 [SecuritySafeCritical]
        public static void
GetAvailableThreads(out int workerThreads, out int
completionPortThreads);
        [SecuritySafeCritical]
        public static void
GetMaxThreads(out int workerThreads, out int
completionPortThreads);
        [SecuritySafeCritical]
        public static void
GetMinThreads(out int workerThreads, out int
completionPortThreads);
        [SecuritySafeCritical]
        public static bool
QueueUserWorkItem(WaitCallback callBack);
        [SecuritySafeCritical]
        public static bool
QueueUserWorkItem(WaitCallback callBack, object state);
}
GetAvailableThreads那些办法再次回到的最大线程池线程数和当前活动线程数之间的差值。
参数 workerThreads: 可用扶持线程的多少。completionPortThreads: 可用异步
I/O 线程的多少。
Get马克斯Threads方法获得当前由线程池维护的帮带线程的最大数目.参数
workerThreads: 线程池中扶植线程的最大额。completionPortThreads:
当前由线程池维护的空余异步 I/O 线程的最大数量。
GetMinThreads方法取伏贴前由线程池维护的悠闲援救线程的一丝一毫数目.参数
workerThreads:
当前由线程池维护的闲暇援助线程的小小数目.completionPortThreads:
当前由线程池维护的空余异步 I/O 线程的十分的小数目。
QueueUserWorkItem方法将艺术排入队列以便施行。参数callBack,
表示要施行的方法.state:富含方法所用数据的靶子。
上面看个例子:

CLXC60线程池分为劳重力线程(workerThreads)I/O线程(completionPortThreads)两种:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace ConsoleApplication6
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             Console.WriteLine("主线程进行异步条用");
14 
15             AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);
16             ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
17             {
18 
19                 Thread.Sleep(1000);
20                 Console.WriteLine("工作任务");
21 
22             }));
23             string s="我的参数";
24             ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
25             {
26                
27                 Thread.Sleep(2000);
28                 Console.WriteLine("工作任务1");
29                 Console.WriteLine(x);
30                
31             }), s);
32             ThreadPool.QueueUserWorkItem(new WaitCallback(MyAsyncOperation), asyncOpIsDone);
33             Console.WriteLine("主线程执行其他");
34             Console.WriteLine("主线程等待任务处理结束");
35             asyncOpIsDone.WaitOne();
36         }
37         static void MyAsyncOperation(Object state)
38         {
39            
40             Thread.Sleep(5000);
41             Console.WriteLine("工作任务2");
42             ((AutoResetEvent)state).Set();
43         }
44     }
45 }
  • 劳重力线程是最重要用作管理CLEvoque内部对象的运营,平时用于总括密集的职分。
  • I/O(Input/Output)线程着重用来与外表系统相互音信,如输入输出,CPU仅需在义务在此以前的时候,将职责的参数字传送递给设备,然后运转硬件装置就可以。等职分成功的时候,CPU收到二个通报,常常的话是四个硬件的间歇时域信号,那时CPU继续后继的拍卖工作。在管理进度中,CPU是不用完全加入管理进度的,若是正在周转的线程不交出CPU的调整权,那么线程也只可以处于等候状态,纵然操作系统将日前的CPU调整给其余线程,那个时候线程所占用的长空还是被占用,而并未CPU处理这几个线程,大概现身线程能源浪费的标题。假如这是三个互连网服务程序,每四个网络连接都采纳叁个线程管理,大概现身大批量线程都在等候网络通信,随着互连网连接的穿梭充实,处于等候意况的线程将会很成本尽全数的内部存款和储蓄器财富。能够思虑使用线程池消除那一个主题素材。

 

  线程池的最大值日常默感觉1000、二零零二。当不仅此数量的伸手时,将维持排队状态,直到线程池里有线程可用。

 运营的结果为

  使用CL本田CR-V线程池的劳引力线程平常常有二种办法:

图片 1

  • 通过ThreadPool.QueueUserWorkItem()方法;
  • 由此信托;

这边有个类为AutoResetEvent,他的魔法是打招呼正在等待的线程已产生事变。他是从EventWaitHandle世襲而来的!例子中分别用了三种分歧的艺术调用,第三种是能够传递参数的!专门的工作线程1就传递了”小编的参数”字符串!专业线程2运行完了会打招呼等待的线程已发惹祸件.这里AutoResetEvent开端化的时候首先将时域信号设成false,职业线程2豆蔻梢头旦调用成功,将被设成true. asyncOpIsDone.WaitOne()梗塞当前线程,直到收届期域信号!

  要小心,无论是由此ThreadPool.QueueUserWorkItem()依然委托,调用的都以线程池里的线程。

再看下边包车型客车例子

经过以下四个主意能够读取和装置CLEscort线程池广东中华南理法高校程公司作者线程与I/O线程的最大线程数。

 

  1. ThreadPool.GetMax(out in workerThreads,out int
    completionPortThreads);
  2. ThreadPool.SetMax(int workerThreads,int completionPortThreads);

 

  若想测量试验线程池中有多少线程正在投入使用,可以由此ThreadPool.GetAvailableThreads(out
in workThreads,out int conoletionPortThreads)方法。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 
 7 namespace ConsoleApplication7
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             Console.WriteLine("n当前线程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
14             Console.WriteLine("当前应用域的名字为:{0}", AppDomain.CurrentDomain.FriendlyName);
15             int workerThreads;
16             int completionPortThreads;
17 
18             AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);//信号初始为空
19             AutoResetEvent asyncOpIsDone2 = new AutoResetEvent(false);
20             ThreadPool.QueueUserWorkItem(new WaitCallback(MyWork), asyncOpIsDone);
21             ThreadPool.QueueUserWorkItem(new WaitCallback(MyWork1), asyncOpIsDone2);
22             ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
23             Console.WriteLine("得当前由线程池维护的辅助线程的最大数目:{0}", workerThreads);
24             ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
25             Console.WriteLine("得当前由线程池维护的空闲辅助线程的最小数目:{0}", workerThreads);
26             /*WaitHandle[] waithandles = new WaitHandle[2];
27             waithandles[0] = asyncOpIsDone;
28             waithandles[1] = asyncOpIsDone2;
29             WaitHandle.WaitAll(waithandles);  */     
30             //或者可以这样
31             asyncOpIsDone.WaitOne();
32             Console.WriteLine("MyWork结束");
33             asyncOpIsDone2.WaitOne();
34             Console.WriteLine("MyWork1结束");
35         }
36         static void MyWork(Object state)
37         {
38             Console.WriteLine("n当前线程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
39             Console.WriteLine("当前应用域的名字为:{0}", AppDomain.CurrentDomain.FriendlyName);
40             Thread.Sleep(2000);
41             ((AutoResetEvent)state).Set();//表示工作已经完成
42         }
43         static void MyWork1(Object state)
44         {
45             Console.WriteLine("n当前线程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
46             Console.WriteLine("当前应用域的名字为:{0}", AppDomain.CurrentDomain.FriendlyName);
47             Thread.Sleep(1000);
48             ((AutoResetEvent)state).Set();//表示工作已经完成
49         }
50 
51     }
52 }
方法 说明
GetAvailableThreads 剩余空闲线程数
GetMaxThreads 最多可用线程数,所有大于此数目的请求将保持排队状态,直到线程池线程变为可用
GetMinThreads 检索线程池在新请求预测中维护的空闲线程数
QueueUserWorkItem 启动线程池里得一个线程(队列的方式,如线程池暂时没空闲线程,则进入队列排队)
SetMaxThreads 设置线程池中的最大线程数
SetMinThreads 设置线程池最少需要保留的线程数

 

咱俩得以使用线程池来消除地点的大部难点,跟使用单个线程比较,使用线程池犹如下优点:

运作结果为

1、减少应用程序的响应时间。因为在线程池中有线程的线程处于等候分配任务状态(只要未有当先线程池的最大上限卡塔 尔(阿拉伯语:قطر‎,无需创造线程。

 

2、不必处理和保安生活周期短暂的线程,不用在创设时为其分配能源,在其推行完职责之后自由能源。

图片 2

3、线程池会依据最近系统天性对池内的线程实行优化管理。

本例中得以详细看AutoRestEvent的用法MyWork1实际上先截至的,不过asyncOpIsDone须求等MyWork的时限信号!所以先输出了MyWork停止.这里还应该有三个东西小编想说的正是WaitHandle,下面的例证已经交给了她的用法!他是AutoRsetEvent的基类.

一言以蔽之使用线程池的成效正是减掉成立和销毁线程的连串开垦。在.NET中有七个线程的类ThreadPool,它提供了线程池的保管。

再有ThreadPool有贰个函数RegisterWaitForSingleObject这么些函数依旧满风趣的!我那边就不再给出例子了!

ThreadPool是二个静态类,它并未有构造函数,对外提供的函数也一切是静态的。个中有一个QueueUserWorkItem方法,它有三种重载情势,如下:

好了,后天就到这了!

public static bool QueueUserWorkItem(WaitCallback
callBack):将艺术排入队列以便施行。此方法在有线程池线程变得可用时实行。

public static bool QueueUserWorkItem(WaitCallback
callBack,Object
state):将艺术排入队列以便实施,并点名包罗该措施所用数据的目标。此形式在有线程池线程变得可用时实践。

QueueUserWorkItem方法中采用的的WaitCallback参数表示一个delegate,它的扬言如下:

public delegate void WaitCallback(Object
state)

倘若急需传递任务音讯方可运用WaitCallback中的state参数,相近于ParameterizedThreadStart委托。

上边是二个ThreadPool的例证,代码如下:

图片 3图片 4

using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp1
{
    class ThreadPoolDemo
    {
        public ThreadPoolDemo()
        {
        }

        public void Work()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(CountProcess));
            ThreadPool.QueueUserWorkItem(new WaitCallback(GetEnvironmentVariables));
        }
        /// <summary>  
        /// 统计当前正在运行的系统进程信息  
        /// </summary>  
        /// <param name="state"></param>  
        private void CountProcess(object state)
        {
            Process[] processes = Process.GetProcesses();
            foreach (Process p in processes)
            {
                try
                {
                    Console.WriteLine("进程信息:Id:{0},ProcessName:{1},StartTime:{2}", p.Id, p.ProcessName, p.StartTime);
                }
                catch (Win32Exception e)
                {
                    Console.WriteLine("ProcessName:{0}", p.ProcessName);
                }
                finally
                {
                }
            }
            Console.WriteLine("获取进程信息完毕。");
        }
        /// <summary>  
        /// 获取当前机器系统变量设置  
        /// </summary>  
        /// <param name="state"></param>  
        public void GetEnvironmentVariables(object state)
        {
            IDictionary list = System.Environment.GetEnvironmentVariables();
            foreach (DictionaryEntry item in list)
            {
                Console.WriteLine("系统变量信息:key={0},value={1}", item.Key, item.Value);
            }
            Console.WriteLine("获取系统变量信息完毕。");
        }
    }
}

ThreadPoolDemo

图片 5图片 6

using System;
using System.Threading;

namespace ConsoleApp1
{

    class Program
    {
        static void Main(string[] args)
        {
            ThreadPoolDemo tpd1 = new ThreadPoolDemo();
            tpd1.Work();
            Thread.Sleep(5000);
            Console.WriteLine("OK");
            Console.ReadLine();
        }
    }
}

Program

 

应用ThreadPool调用专门的职业线程和IO线程的模范

图片 7图片 8

using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;

namespace ConsoleApp1
{

    class Program
    {
        static void Main(string[] args)
        {
            // 设置线程池中处于活动的线程的最大数目
            // 设置线程池中工作者线程数量为1000,I/O线程数量为1000
            ThreadPool.SetMaxThreads(1000, 1000);
            Console.WriteLine("Main Thread: queue an asynchronous method");
            PrintMessage("Main Thread Start");

            // 把工作项添加到队列中,此时线程池会用工作者线程去执行回调方法            
            ThreadPool.QueueUserWorkItem(asyncMethod);
            asyncWriteFile();
            Console.Read();
        }

        // 方法必须匹配WaitCallback委托
        private static void asyncMethod(object state)
        {
            Thread.Sleep(1000);
            PrintMessage("Asynchoronous Method");
            Console.WriteLine("Asynchoronous thread has worked ");
        }


        #region 异步读取文件模块
        private static void asyncReadFile()
        {
            byte[] byteData = new byte[1024];
            FileStream stream = new FileStream(@"D:123.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
            //把FileStream对象,byte[]对象,长度等有关数据绑定到FileDate对象中,以附带属性方式送到回调函数
            Hashtable ht = new Hashtable();
            ht.Add("Length", (int)stream.Length);
            ht.Add("Stream", stream);
            ht.Add("ByteData", byteData);

            //启动异步读取,倒数第二个参数是指定回调函数,倒数第一个参数是传入回调函数中的参数
            stream.BeginRead(byteData, 0, (int)ht["Length"], new AsyncCallback(Completed), ht);
            PrintMessage("asyncReadFile Method");
        }

        //实际参数就是回调函数
        static void Completed(IAsyncResult result)
        {
            Thread.Sleep(2000);
            PrintMessage("asyncReadFile Completed Method");
            //参数result实际上就是Hashtable对象,以FileStream.EndRead完成异步读取
            Hashtable ht = (Hashtable)result.AsyncState;
            FileStream stream = (FileStream)ht["Stream"];
            int length = stream.EndRead(result);
            stream.Close();
            string str = Encoding.UTF8.GetString(ht["ByteData"] as byte[]);
            Console.WriteLine(str);
            stream.Close();
        }
        #endregion

        #region 异步写入文件模块
        //异步写入模块
        private static void asyncWriteFile()
        {
            //文件名 文件创建方式 文件权限 文件进程共享 缓冲区大小为1024 是否启动异步I/O线程为true
            FileStream stream = new FileStream(@"D:123.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
            //这里要注意,如果写入的字符串很小,则.Net会使用辅助线程写,因为这样比较快
            byte[] bytes = Encoding.UTF8.GetBytes("你在他乡还好吗?");
            //异步写入开始,倒数第二个参数指定回调函数,最后一个参数将自身传到回调函数里,用于结束异步线程
            stream.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(Callback), stream);
            PrintMessage("AsyncWriteFile Method");
        }

        static void Callback(IAsyncResult result)
        {
            //显示线程池现状
            Thread.Sleep(2000);
            PrintMessage("AsyncWriteFile Callback Method");
            //通过result.AsyncState再强制转换为FileStream就能够获取FileStream对象,用于结束异步写入
            FileStream stream = (FileStream)result.AsyncState;
            stream.EndWrite(result);
            stream.Flush();
            stream.Close();
            asyncReadFile();
        }
        #endregion

        // 打印线程池信息
        private static void PrintMessage(String data)
        {
            int workthreadnumber;
            int iothreadnumber;

            // 获得线程池中可用的线程,把获得的可用工作者线程数量赋给workthreadnumber变量
            // 获得的可用I/O线程数量给iothreadnumber变量
            ThreadPool.GetAvailableThreads(out workthreadnumber, out iothreadnumber);

            Console.WriteLine("{0}n CurrentThreadId is {1}n CurrentThread is background :{2}n WorkerThreadNumber is:{3}n IOThreadNumbers is: {4}n",
                data,
                Thread.CurrentThread.ManagedThreadId,
                Thread.CurrentThread.IsBackground.ToString(),
                workthreadnumber.ToString(),
                iothreadnumber.ToString());
        }
    }
}

Program

 

线程池中放入异步操作

图片 9图片 10

using System;
using System.Threading;

namespace ConsoleApp1
{

    class Program
    {
        private static void AsyncOperation(object state)
        {
            Console.WriteLine("Operation state: {0}", state ?? "(null)");
            Console.WriteLine("Worker thread id: {0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(TimeSpan.FromSeconds(2));
        }

        static void Main(string[] args)
        {
            const int x = 1;
            const int y = 2;
            const string lambdaState = "lambda state 2";

            ThreadPool.QueueUserWorkItem(AsyncOperation);
            Thread.Sleep(TimeSpan.FromSeconds(1));

            ThreadPool.QueueUserWorkItem(AsyncOperation, "async state");
            Thread.Sleep(TimeSpan.FromSeconds(1));

            ThreadPool.QueueUserWorkItem(state => {
                Console.WriteLine("Operation state: {0}", state);
                Console.WriteLine("Worker thread id: {0}", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }, "lambda state");

            ThreadPool.QueueUserWorkItem(_ =>
            {
                Console.WriteLine("Operation state: {0}, {1}", x + y, lambdaState);
                Console.WriteLine("Worker thread id: {0}", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }, "lambda state");

            Thread.Sleep(TimeSpan.FromSeconds(2));
        }
    }
}

Program

 

线程池同步操作

图片 11图片 12

using System;
using System.Threading;

namespace ConsoleApp1
{
    class ThreadPoolDemo
    {
        static object lockobj = new object();
        static int Count = 0;
        ManualResetEvent manualEvent;
        public ThreadPoolDemo(ManualResetEvent manualEvent)
        {
            this.manualEvent = manualEvent;
        }
        public void DisplayNumber(object a)
        {

            lock (lockobj)
            {
                Count++;
                Console.WriteLine("当前运算结果:{0},Count={1},当前子线程id:{2} 的状态:{3}", a, Count, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ThreadState);
            }
            //Console.WriteLine("当前运算结果:{0}", a);
            //Console.WriteLine("当前运算结果:{0},当前子线程id:{1} 的状态:{2}", a,Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ThreadState);
            //这里是方法执行时间的模拟,如果注释该行代码,就能看出线程池的功能了
            Thread.Sleep(2000);
            //Console.WriteLine("当前运算结果:{0},Count={1},当前子线程id:{2} 的状态:{3}", a, Count, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ThreadState);
            //这里是释放共享锁,让其他线程进入
            manualEvent.Set();


        }
    }
}

ThreadPoolDemo

图片 13图片 14

using System;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp1
{

    class Program
    {
        //设定任务数量 
        static int count = 10;
        static void Main(string[] args)
        {
            //让线程池执行5个任务所以也为每个任务加上这个对象保持同步
            ManualResetEvent[] events = new ManualResetEvent[count];
            Console.WriteLine("当前主线程id:{0}", Thread.CurrentThread.ManagedThreadId);

            Stopwatch sw = new Stopwatch();
            sw.Start();
            NoThreadPool(count);
            sw.Stop();
            Console.WriteLine("Execution time using threads: {0}", sw.ElapsedMilliseconds);


            sw.Reset();
            sw.Start();
            //循环每个任务
            for (int i = 0; i < count; i++)
            {
                //实例化同步工具
                events[i] = new ManualResetEvent(false);
                //Test在这里就是任务类,将同步工具的引用传入能保证共享区内每次只有一个线程进入
                ThreadPoolDemo tst = new ThreadPoolDemo(events[i]);
                //Thread.Sleep(200);
                //将任务放入线程池中,让线程池中的线程执行该任务                 
                ThreadPool.QueueUserWorkItem(tst.DisplayNumber, i);
            }
            //注意这里,设定WaitAll是为了阻塞调用线程(主线程),让其余线程先执行完毕,
            //其中每个任务完成后调用其set()方法(收到信号),当所有
            //的任务都收到信号后,执行完毕,将控制权再次交回调用线程(这里的主线程)
            ManualResetEvent.WaitAll(events);
            sw.Stop();
            Console.WriteLine("Execution time using threads: {0}", sw.ElapsedMilliseconds);
            //Console.WriteLine("所有任务做完!");
            Console.ReadKey();
        }

        static void NoThreadPool(int count)
        {
            for (int i = 0; i < count; i++)
            {
                Thread.Sleep(2000);
                Console.WriteLine("当前运算结果:{0},Count={1},当前子线程id:{2} 的状态:{3}", i, i + 1, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.ThreadState);
            }
        }

    }
}

Program

 

线程池中的撤除操作

图片 15图片 16

using System;
using System.Threading;

namespace ConsoleApp1
{

    class Program
    {
        static void Main(string[] args)
        {
            ThreadPool.SetMaxThreads(1000, 1000);
            Console.WriteLine("Main thread run");
            PrintMessage("Start");
            Run();
            Console.ReadKey();
        }

        private static void Run()
        {
            CancellationTokenSource cts = new CancellationTokenSource();

            // 这里用Lambda表达式的方式和使用委托的效果一样的,只是用了Lambda后可以少定义一个方法。
            // 这在这里就是让大家明白怎么lambda表达式如何由委托转变的
            ////ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));
            ThreadPool.QueueUserWorkItem(callback, cts.Token);

            Console.WriteLine("Press Enter key to cancel the operationn");
            Console.ReadLine();

            // 传达取消请求            
            cts.Cancel();
            Console.ReadLine();
        }

        private static void callback(object state)
        {
            Thread.Sleep(1000);
            PrintMessage("Asynchoronous Method Start");
            CancellationToken token = (CancellationToken)state;
            Count(token, 1000);
        }

        // 执行的操作,当受到取消请求时停止数数
        private static void Count(CancellationToken token, int countto)
        {
            for (int i = 0; i < countto; i++)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Count is canceled");
                    break;
                }

                Console.WriteLine(i);
                Thread.Sleep(300);
            }

            Console.WriteLine("Cout has done");
        }

        // 打印线程池信息
        private static void PrintMessage(String data)
        {
            int workthreadnumber;
            int iothreadnumber;

            // 获得线程池中可用的线程,把获得的可用工作者线程数量赋给workthreadnumber变量
            // 获得的可用I/O线程数量给iothreadnumber变量
            ThreadPool.GetAvailableThreads(out workthreadnumber, out iothreadnumber);

            Console.WriteLine("{0}n CurrentThreadId is {1}n CurrentThread is background :{2}n WorkerThreadNumber is:{3}n IOThreadNumbers is: {4}n",
                data,
                Thread.CurrentThread.ManagedThreadId,
                Thread.CurrentThread.IsBackground.ToString(),
                workthreadnumber.ToString(),
                iothreadnumber.ToString());
        }
    }
}

Program

 

Thread与ThreadPool的一个属性相比较

图片 17图片 18

using System;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            const int numberOfOperations = 300;
            var sw = new Stopwatch();
            sw.Start();
            UseThreads(numberOfOperations);
            sw.Stop();
            Console.WriteLine("Execution time using threads: {0}", sw.ElapsedMilliseconds);

            sw.Reset();
            sw.Start();
            UseThreadPool(numberOfOperations);
            sw.Stop();
            Console.WriteLine("Execution time using threadPool: {0}", sw.ElapsedMilliseconds);
        }

        static void UseThreads(int numberOfOperations)
        {
            using (var countdown = new CountdownEvent(numberOfOperations))
            {
                Console.WriteLine("Scheduling work by creating threads");
                for (int i = 0; i < numberOfOperations; i++)
                {
                    var thread = new Thread(() => {
                        Console.Write("{0},", Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep(TimeSpan.FromSeconds(0.1));
                        countdown.Signal();
                    });
                    thread.Start();
                }
                countdown.Wait();
                Console.WriteLine();
            }
        }

        static void UseThreadPool(int numberOfOperations)
        {
            using (var countdown = new CountdownEvent(numberOfOperations))
            {
                Console.WriteLine("Starting work on a threadpool");
                for (int i = 0; i < numberOfOperations; i++)
                {
                    ThreadPool.QueueUserWorkItem(_ => {
                        Console.Write("{0},", Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep(TimeSpan.FromSeconds(0.1));
                        countdown.Signal();
                    });
                }
                countdown.Wait();
                Console.WriteLine();
            }
        }
    }
}

Program

 

 

 

 

 

admin

网站地图xml地图