.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秒内通过该断点,否则管理器不会启动服务。。。
浙公网安备 33010602011771号