.Net多线程程序设计学习笔记----创建托管线程和访问OS线程

来源:互联网 发布:京东淘宝网购物商城 编辑:程序博客网 时间:2024/04/29 23:24

 多线程是提高应用程序响应灵敏度的常用方式,我们通常将需要花费大量时间的计算任务放到后台线程中去执行,这样用户界面就可以继续接收用户的命令.而不需要等待任务的结束.但是在单处理器的系统中,太多的线程反而会降低系统的性能,因为系统需要更多的时间来进行线程的切换.下面主要介绍一下:在.net 中创建托管线程和访问OS线程信息的方法;异步委托调用的实现;线程同步.
一.在.net 中创建托管线程和访问OS线程信息的方法
在.NET中通过System.Threading.Thread类来表示托管线程.一个托管线程不对应于一个系统线程,它是CLR的逻辑线程有CLR来维护线程信息.托管线程有两种类型:线程池线程和非线程池线程.下面非别介绍一下各种线程的创建方法:
1.线程池线程:线程池为我们提供了大量的可利用的线程资源,线程的使用可以大大减少我们申请新的线程资源的之间.我们可以通过ThreadPool.QueueUserWorkItem(WaitCallBack);来向线程池中添加线程.如下:

using System;
using System.Threading;

namespace ConsoleApplication1
{
    
class Program
    {
        
static void Main(string[] args)
        {
            WaitCallback thread 
= new WaitCallback(ThreadPro);
            ThreadPool.QueueUserWorkItem(thread, 
"Thread:");
            Console.ReadLine();

        }

        
static void ThreadPro(object stateInfo)
        {
            Console.WriteLine(stateInfo.ToString());
        }
    }
}
上面是创建了一个简单的线程池线程,QueueUserWorkItem接受一个WaitCallback类型的委托参数和一个可选的传递给委托的object参数.我们通过使用QueueUserWorkItem方法让ThreadPool创建了一个从ThreadPro开始执行的线程,我们自己是没法显示创建线程池线程的,也没有办法获得线程池中任何一个线程的引用.这意味着我们不能够亲自控制线程(如终止线程,线程何时执行完成).线程池是有一定容量的,默认是25.当线程池线程已经饱和时,新加入的线程只有等待线程池中的某个线程释放了线程资源时才能开始执行.
using System;
using System.Threading;

namespace ConsoleApplication1
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//显示可容纳的工作线程和异步IO线程
            int maxWorkThread, maxCompletionThread;
            ThreadPool.GetMaxThreads(
out maxWorkThread, out maxCompletionThread);
            Console.WriteLine(
"maxWorkThread={0};maxCompletionThread={1}",maxWorkThread, maxCompletionThread);
             //创建100个线程池线程
            Console.WriteLine(
"stateInfo  在线程池中的标识  当前可用的线程");
            
for (int i = 0; i < 100; i++)
            {
                WaitCallback thread 
= new WaitCallback(ThreadPro);
                ThreadPool.QueueUserWorkItem(thread, 
"Thread:"+i);
            }
            Console.Read();

        }
        
//线程执行入口,显示线程信息   "stateInfo    在线程池中的标识   当前可用的线程"
        static void ThreadPro(object stateInfo)
        {
            Random r 
= new Random();
            
int available, total;
            ThreadPool.GetAvailableThreads(
out available, out total);
            Console.WriteLine(
"{0}       {1}        {2}   ",stateInfo.ToString(),Thread.CurrentThread.ManagedThreadId,available);
            Thread.Sleep(r.Next(
5000,10000));
        }
    }
}
从上面的程序输出我们可以看到:加入线程池中的线程只有在有可有的线程时才会得到执行;加入线程池中的线程无法取消;
2.非线程池线程;我们可以通过System.Threading.Thread来显示的创建一个非线程池线程,这样我们可以直接控制线程的行为.
using System;
using System.Threading;

namespace ConsoleApplication1
{
    
class Program
    {
        
static void Main(string[] args)
        {
            ParameterizedThreadStart parameterizedThreadStart
=new ParameterizedThreadStart(ThreadPro);
            Thread thread 
= new Thread(parameterizedThreadStart);
            thread.Start(
"thread");
            Console.Read();

        }
        
//线程执行入口,显示线程信息   "stateInfo    后台线程   线程池线程"
        static void ThreadPro(object stateInfo)
        {
            Random r 
= new Random();
            Console.WriteLine(
"{0}       {1}        {2}   ",stateInfo.ToString(),
                Thread.CurrentThread.IsBackground,Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(r.Next(
5000,10000));
        }
    }
}
Thread构造函数可以接受一个ParameterizedThreadStart(带一个object类型的参数)delegate或者threadSstart(不带参数)的delegate.
3.访问非托管线程信息:System.Diagnostics.ProcessThread表示一个非托管线程.
using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
//列举出当前系统的所有运行进程和它包含的线程
            Process[] processes=Process.GetProcesses();
            
foreach (Process pro in processes)
            {
                Console.WriteLine(
"Process Name:{0},Process ID {1},ThreadCount:{2}", pro.ProcessName, pro.Id,pro.Threads.Count);
                
foreach (ProcessThread processThread in pro.Threads)
                {
                    Console.WriteLine(
"    Thread  ID:{0},STATE:{1}", processThread.Id, processThread.ThreadState);
                }
            }
            Console.Read();

        }
    }
}
未完待续....
原创粉丝点击