四线程编程学习笔记——线程池(一)新匍京视频在线

② 、     线程池中放入异步操作

新匍京视频在线 1

 新匍京视频在线 2

2.程序执行结果如下图。

新匍京视频在线 3

    
.NET中的线程池是受CLHaval管理的,TheadTool类有一个QueueUserWorkItem静态方法,这一个静态方法接受一个信托,代表用户自定义的2个异步操作,在这么些点子被调用之后,委托会进入到当中队列中,假诺池中从不线程,则创设三个做事线程,把第①个委托放入工作线程。假设持续放入委托,则池创设新的办事线程,直到工作线程数量达到上限。那时再放入委托,则不会创建新的干活线程,而是在队列中伺机,直到有空暇的做事线程。

      
代码中的调用Thread.sleep方法,是为了让线程池中的工作线程为新操作重用。请留心打字与印刷出来的ThradId,假如ThreadID一样则表达五个操作重用了同二个做事线程。

     
线程池,正是我们先分配一些能源到池塘里,当大家须要接纳时,则从池子中赢得,用完了,再放回池子里。

 

 

  接上文 四线程编制程序学习笔记——线程同步(三)

     
假设你有卓殊多的施行时间尤其短的操作,那么适合营用线程池来进步功用,而不是活动创立二十多线程。

 1.代码之类:

 新匍京视频在线 4

      
上面的程序运营时,我们率先创立线程来执行委托操作,然后调用委托的BeginInvoke来施行回调方法,那个回调函数会在异步操作完结今后会被调用,并且会把一个自定义的值传给那么些回调函数,最终大家会得到2个贯彻了IAsyncResult接口的result对象,当线程池的干活线程在展开工作时,允许大家接二连三其余操作。我们得以轮询result对象的IsCompleted属性,鲜明操作是不是成功。也能够调用EndInvoke将IAsyncResult传给委托参数。

      
程序首先定义了1个AsyncOper方法,然后使用QueueUserWorkItem将那几个艺术放入线程池中,然后重新放入2个AsyncOper方法,不过本次给艺术调用传一个对象。

 

2.实施结果如下。程序执行了四遍。

 

  接上文 四线程编程学习笔记——线程同步(三)

      
程序首先定义了一个AsyncOper方法,然后使用QueueUserWorkItem将以此措施放入线程池中,然后再次放入一个AsyncOper方法,可是这一次给艺术调用传二个目的。

 接上文 三十二线程编制程序学习笔记——线程同步(二)

    
.NET中的线程池是受CL本田UR-V管理的,TheadTool类有一个QueueUserWorkItem静态方法,那么些静态方法接受二个寄托,代表用户自定义的1个异步操作,在那一个主意被调用之后,委托会进入到内部队列中,假使池中绝非线程,则创制二个工作线程,把第②个委托放入工作线程。假诺后续放入委托,则池创制新的行事线程,直到工作线程数量达到上限。那时再放入委托,则不会创制新的劳作线程,而是在队列中伺机,直到有空余的干活线程。

壹 、     线程池中调用委托

 

二 、     线程池中放入异步操作

 1.代码之类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; 

namespace ThreadPoolDemo
{ 
    class Program
    {   

        static void Main(string[] args)
        {
            Console.WriteLine("开始测试线程池-QueueUserWorkItem。。。");
            const int x = 1;
            const int y = 2;
            string workState = "工作状态 2"; 

            ThreadPool.QueueUserWorkItem(AsyncOper);
            Thread.Sleep(1000);
            ThreadPool.QueueUserWorkItem(AsyncOper,"同步状态");
            Thread.Sleep(1000);

            ThreadPool.QueueUserWorkItem(status => {
                Console.WriteLine("操作状态 {0} ", status);
                Console.WriteLine("线程池中工作线程ID :{0}", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            },"工作状态");


            ThreadPool.QueueUserWorkItem(_ => {
                Console.WriteLine("操作结果x+y= {0} ,{1}", x+y,workState);
                Console.WriteLine("线程池中工作线程ID :{0}", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }, "工作状态"); 

            Thread.Sleep(2000);
            Console.Read();
        }

        private static void  AsyncOper(object status)
        {
            Console.WriteLine("操作状态 :{0} ",status??"null");

            Console.WriteLine("工作线程在线程池在的ID :{0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(2000);
        }  

    }
}

      
注意:放入线程池中的操作供给的年华要短,不要把必要长日子运作的操作放入线程池中,或不通工作线程。那将促成品质难题和至极不便调用的题材。

 

                
在ASP.NET中使用线程池要当心,ASP.NET中的线程池是3个共用线程池,若是线程池中的工作线程都用完了,则会促成WEB服务器对健康的HTTP请求不大概提供劳务。

                
在ASP.NET中使用线程池要警醒,ASP.NET中的线程池是三个共用线程池,假使线程池中的工作线程都用完了,则会促成WEB服务器对健康的HTTP请求不可能提供服务。

     
假设您有相当多的实行时间尤其短的操作,那么适同盟用线程池来升高成效,而不是电动成立八线程。

 

 

      
上边的程序运维时,大家率先创制线程来执行委托操作,然后调用委托的BeginInvoke来施行回调方法,那么些回调函数会在异步操作完毕以往会被调用,并且会把一个自定义的值传给这么些回调函数,最终我们会获取四个贯彻了IAsyncResult接口的result对象,当线程池的办事线程在开始展览工作时,允许大家继续其余操作。我们得以轮询result对象的IsCompleted属性,分明操作是还是不是达成。也能够调用EndInvoke将IAsyncResult传给委托参数。

 

 

 接上文 十六线程编制程序学习笔记——线程同步(一)

 

2.履行结果如下。程序执行了两次。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; 

namespace ThreadPoolDemo
{ 
    class Program
    {   

        static void Main(string[] args)
        {
            Console.WriteLine("开始测试线程池-QueueUserWorkItem。。。");
            const int x = 1;
            const int y = 2;
            string workState = "工作状态 2"; 

            ThreadPool.QueueUserWorkItem(AsyncOper);
            Thread.Sleep(1000);
            ThreadPool.QueueUserWorkItem(AsyncOper,"同步状态");
            Thread.Sleep(1000);

            ThreadPool.QueueUserWorkItem(status => {
                Console.WriteLine("操作状态 {0} ", status);
                Console.WriteLine("线程池中工作线程ID :{0}", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            },"工作状态");


            ThreadPool.QueueUserWorkItem(_ => {
                Console.WriteLine("操作结果x+y= {0} ,{1}", x+y,workState);
                Console.WriteLine("线程池中工作线程ID :{0}", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }, "工作状态"); 

            Thread.Sleep(2000);
            Console.Read();
        }

        private static void  AsyncOper(object status)
        {
            Console.WriteLine("操作状态 :{0} ",status??"null");

            Console.WriteLine("工作线程在线程池在的ID :{0}", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(2000);
        }  

    }
}

      
代码中的调用Thread.sleep方法,是为着让线程池中的工作线程为新操作重用。请小心打字与印刷出来的ThradId,假如ThreadID一样则评释八个操作重用了同多少个工作线程。

 接上文 二十四线程编制程序学习笔记——线程同步(二)

 1.代码之类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; 

namespace ThreadPoolDemo
{


    public delegate string ThreadPoolRun(out int threadId);
    class Program
    {  

        static void Main(string[] args)
        {

            Console.WriteLine("开始测试线程池-委托。。。");
            int threadId = 0;
            ThreadPoolRun poolDele = RunThread;
            var t = new Thread(() => RunThread(out threadId));
            t.Start();
            t.Join();
            Console.WriteLine("线程ID {0} ",threadId);
            IAsyncResult r = poolDele.BeginInvoke(out threadId, Callback, "在线程池中同步调用回调函数");
            string result = poolDele.EndInvoke(out threadId, r);
            Console.WriteLine("线程池中工作线程ID :{0}", threadId);
            Console.WriteLine("返回结果:{0}",result); 

            Thread.Sleep(2000);
            Console.Read(); 

        }

        private static void  Callback(IAsyncResult r)
        {

            Console.WriteLine("开始调用回调函数。。。");
            Console.WriteLine("回调函数此时的状态 :{0}",r.AsyncState);
            Console.WriteLine("调用此回调函数的线程是否在线程池 :{0}", Thread.CurrentThread.IsThreadPoolThread);
            Console.WriteLine("调用此回调函数的线程在线程池在的ID :{0}", Thread.CurrentThread.ManagedThreadId);
        }

        private static string RunThread(out int threadId)
        {
            Console.WriteLine("开始工作。。。");       

            Console.WriteLine("调用此回调函数的线程是否在线程池 :{0}", Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            threadId = Thread.CurrentThread.ManagedThreadId;
            return string.Format("此线程在线程池在的ID :{0}", threadId);
        }
    }
}

 接上文 十六线程编制程序学习笔记——线程同步(一)

2.程序执行结果如下图。

     
制造多线程操作是可怜高昂的,所以种种运营时刻非常的短的操作,创制八线程进行操作,恐怕并不可能提升效用,反而下跌了频率。

新匍京视频在线,     
创制二十多线程操作是老大昂贵的,所以各个运转时刻尤其短的操作,创立八线程进行操作,大概并无法升高成效,反而下跌了作用。

      
当线程池中负有操作都成功,而且尚未新任务操作时,线程池会释放长日子不用的财富。

壹 、     线程池中调用委托

 1.代码之类:

     
线程池,便是大家先分配一些财富到池塘里,当大家须求使用时,则从池塘中赢得,用完了,再放回池子里。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; 

namespace ThreadPoolDemo
{


    public delegate string ThreadPoolRun(out int threadId);
    class Program
    {  

        static void Main(string[] args)
        {

            Console.WriteLine("开始测试线程池-委托。。。");
            int threadId = 0;
            ThreadPoolRun poolDele = RunThread;
            var t = new Thread(() => RunThread(out threadId));
            t.Start();
            t.Join();
            Console.WriteLine("线程ID {0} ",threadId);
            IAsyncResult r = poolDele.BeginInvoke(out threadId, Callback, "在线程池中同步调用回调函数");
            string result = poolDele.EndInvoke(out threadId, r);
            Console.WriteLine("线程池中工作线程ID :{0}", threadId);
            Console.WriteLine("返回结果:{0}",result); 

            Thread.Sleep(2000);
            Console.Read(); 

        }

        private static void  Callback(IAsyncResult r)
        {

            Console.WriteLine("开始调用回调函数。。。");
            Console.WriteLine("回调函数此时的状态 :{0}",r.AsyncState);
            Console.WriteLine("调用此回调函数的线程是否在线程池 :{0}", Thread.CurrentThread.IsThreadPoolThread);
            Console.WriteLine("调用此回调函数的线程在线程池在的ID :{0}", Thread.CurrentThread.ManagedThreadId);
        }

        private static string RunThread(out int threadId)
        {
            Console.WriteLine("开始工作。。。");       

            Console.WriteLine("调用此回调函数的线程是否在线程池 :{0}", Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.FromSeconds(2));
            threadId = Thread.CurrentThread.ManagedThreadId;
            return string.Format("此线程在线程池在的ID :{0}", threadId);
        }
    }
}

      
当线程池中持有操作都形成,而且没有新职务操作时,线程池会释放长日子不用的能源。

      
注意:放入线程池中的操作须要的时光要短,不要把须求长日子运作的操作放入线程池中,或堵塞工作线程。那将造成品质难点和相当麻烦调用的标题。

相关文章