.NET企业开发之多线程和windows服务

本章摘要:

1.如何创建多线程应用程序

2.如何创建windows后台服务

3.如何安装和卸载windows服务

4.在windows服务中使用多线程

每个.net应用程序都有一个主入口就是Main()函数,在该函数定义之前,通常会看到一个独特的代码属性[STAThread],其含义是指定应用程序的默认线程模型是单线程单元(STA)。

        一个应用程序的启动线程模型可设置为单线程单元(STA)或多线程单元(MTA)。如果应用程序没有设置这个代码属性,则该线程不被初始化。简单的说,每个应用程序在启动时都将在当前应用程序域(AppDomain)中创建一个主线程,否则应用程序就不能运行。

       

        在应用程序运行时,除了主线程外,还可以创建新的线程,以便进行执行某些操作。比如在访问远程网络资源时,为了避免客户端过长的处于等待状态,就可以开一个新线程来执行网络访问的操作,这样客户端可以继续其它的操作。

创建新线程可以通过位于System.Threading命名空间下的Thread类和ThreadStart委托可以建立新的线程。

private void newThreadCode()

{

    try

       {

             TcpClient tcpcnt = new TcpClient("localhost",8085);

             StreamReader sr = new StreamReader(tcpcnt.GetStream());

             this.textBox1.Text = sr.ReadToEnd();

             sr.Close();

        }

    catch

       {

             this.textBox1.Text = ex.Message;

        }

}

private void button1_Click(object sender, System.EventArgs e)

{

    Thread thd = new Thread(new ThreadStart(this.newThreadCode));//通过委托建立新的线程

    thd.Start();

}

设置优先级:

             thd.Priority \ System.Threading.ThreadPriority.Highest;//Highest可以用AboveNormal,Normal,BelowNormal,Lowest替换

线程启动后,如果需要控制该县城的一些运行状态,那么可以直接通过thd对象来实现。比如我们要挂起县城,可以使用如下代码:

       thd.Suspend();

要重启挂起的线程重启,则使用如下代码:

       thd.Resume();

在需要终止thd线程时,由于主线程与thd线程是独立运行的,所以有可能在我们想去终止thd线程是,thd线程实际上已经结束了,这样就可能会产生null引用错误,为了防止这样的运行时异常,需要使用如下代码:

    if(thd!=null)

    {

          thd.Abort();

    }

在与COM交互时,如果我们需要修改线程的单元模式,可以通过设置线程的ApartmentState属性来实现。该属性值是ApartmentState枚举类型值,比如我们要设置当前新建的线成为单线程单元,可使用如下代码:

       thd.ApartmentState = System.Threading.ApartmentState.STA;//STA可以用MTA,Unknown代替,Unknown指尚未设置ApartmentState属性,默认值

       线程的名称的设置:

                   Thread thd1 = new Thread(new ThreadStart(this.newThreadCode1));

                   thd1.Name = "thd1";

11.1.3     访问主线程

             Thread mainThd = Thread.CurrentThread;

   

    (

       listBox用法:

                this.listBox1.Items.Add(mainThd.CurrentCulture.DisplayName.ToString());

                this.listBox2.Items.Add(mainThd.Priority.ToString());

    )

11.1.4     线程同步

主要通过:

1.lock方法锁定(lock只能锁定引用类型的资源,不能锁定值类型资源)

    lock(myDataSet)

    {

    }

2.通过Monitor类向单个线程授予对象锁来控制对象的访问。

    System.Threading.Monitor.Enter(myDataSet);

    try{}

    catch(Exception ex)

    {}

    finally

    {

       System.Threading.Monitor.Exit(myDataSet);

    }

3. 线程同步除了可以通过lock实现资源的独占性顺序访问,还可以通过volatile关键字实现实时地访问其他线程可能修改的变量和对象。

11.2

通过System.ServiceProcess命名空间下的类来控制这些Windows服务

通过ServerController类来停止Stop(),Start()或者Pause()某个服务,当某个服务不能被Pause时,会产生运行时异常。

通过WMI(windows管理规范(management   instrument)来实现)

ManagementObject mgo = new ManagementObject(“Win32_Service.Name='Dhcp' ”);//Dhcp只是举例,可以替换其他的服务的名称

mgo.InvokeMethod("StartService",null);

mgo.InvokeMethod("StopService",null);//停止

mgo.InvokeMethod("PauseService",null);//暂停

用WMI方法返回为正数,但是用mgo.InvokeMethod()方法时返回值被封装为Object类型,如果需要获取真正的整型返回值,则可以通过如下代码实现:

          int  returnValue = Convert.ToInt32(mgo.InvokeMethod("StopService",null));

11.2.3

编写windows服务

//远程通信的服务端,TCP]服务端等都需要以后台服务来运行。。。

每个windows服务通过集成了System.ServiceProcess.ServiceBase类来实现的。。。

通过重载OnStart()和OnStop()函数来实现windows服务框架

11.3

安装和卸载windows服务

InstaullUtil 服务名.exe        安装后就可以在服务管理器中查看到我们新创建的服务,并且能启动和停止该服务

InstaullUtil /u 服务名.exe    //卸载服务命令

//上述两个命令都只能在.net 命令行工具中运行

11.4   调试windows服务

附加到windows服务的进程能够调试大多数windows服务代码,但是有些代码是不能够调试的。比如,由于服务已经启动,因此不能用这种方法调试服务的OnStart方法中的代码,或调试用于加载服务的Main方法中的代码。

技巧:

            如果调试OnStart方法中的代码,则必须在30秒内通过该断点,否则管理器不会启动服务。。。         

posted @ 2012-02-23 18:51  therockthe  阅读(563)  评论(0)    收藏  举报