前几天做项目的时候需要用到window服务,研究一段时间,算是掌握了最基本的使用方法吧,现总结如下:

  引言:在项目过程中碰到一个问题:需要不断的扫描一个大型数据库表,并获取dataset,以便做后续的复杂的逻辑处理。如果直接扫描获取并做逻辑处理,势必会有很大的性能负耗。现在使用windows服务扫描其变化而不获取dataset,只有当windows服务告诉我可以获取dataset时再进行获取,并做逻辑处理,大大提高了其性能。

  windows服务应用程序是一个没有前台界面的应用程序,同时其占用内存资源较小便于长期运行,因此被众多编程者使用,多用于服务器环境下。由于其没有用户界面因此不会产生可视输出,并且可以对其启动和停止进行按需设定,非常方便。

一、创建windows服务:

平台:vs2010

工具:c#

功能实现:向一个txt文件写入当前时间。(完全是学习练习使用,所有没有涉及到特殊的功能)

首先在vs2010中创建一个windows服务工程,默认有一个service1.cs文件,打开此文件,创建一个计时器,每隔1秒钟扫描一次。在计时器的t1_Elapsed中添加编写日志的方法(writelog)。

Onstart控制服务启动;Onstop:控制服务停止。

在OnStart中加入计时器启动的方法,OnStop中加入计时器停止的方法。至此便完成一个简单的Windows服务的创建。

参考代码:

 System.Timers.Timer t1 = new System.Timers.Timer();
public Service1()
{
InitializeComponent();
t1.Interval = ;
t1.Elapsed += new System.Timers.ElapsedEventHandler(t1_Elapsed);
} void t1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Writelog(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
}
protected override void OnStart(string[] args)
{
t1.Start();
} protected override void OnStop()
{
t1.Stop();
}

二、安装、发布windows服务:

  将service1.cs的视图设计器打开,右键点击添加按照程序,显现serviceProcessInstaller1和serviceInstaller1两个组件,点击serviceProcessInstaller1的属性,将其改为LocalService,点击serviceInstaller1的属性,可以在serviceName中更改服务的名字,在startType中更改服务的启动方式。最后生成解决方案。

使用InstallUtil.exe工具,安装生成的应用程序。提示:在解决方案生成的项目应用程序的目录下进行安装,可以debug,也可以是release。

在安装过程中可以使用批命令来实现:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil -u FirstService.exe

C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil  FirstService.exe

其中前面是InstallUtil.exe的存放位置,可以根据不同的版本查找其确切位置。FirstService是应用程序,可以替换为项目生成的应用程序。

注:在安装过程中如果一切顺利当然是幸事,本人的安装足是用了两个下午,最后在一大牛的指导下才安装正确。究其原因,检查你使用的计算机的用户是否对你项目所在位置的盘是否赋予其相应的权利(管理员)。(深受其苦)

三、调试windows服务:

1、将创建的windows服务发布到本地系统中。

2、打开vs2010,在项目源代码中设置断点。

3、点击调试按钮,打开附件到进程对话框,选择所需要进程后点击附加按钮。

4、启动服务即可进行调试。

windows服务成功完成后,原本是想在不同的进程间建立通信,最后经过询问先驱者,本项目的需求是当数据有改变时将其变化保持到另一数据库表即可,完成目标。但是这里勾起了我学习进程间通信的好奇心。

进程间通信方式:

匿名管道:半双工通信方式,数据只能在有亲缘关系的进程间单向流动。通俗来讲:用来在父进程和子进程间传输数据,并且是在本机上使用。

命名管道:相对应匿名管道来说的,单向或双向的,用在服务端和一个或多个客户端进行通讯。一个命名管道的所有实例共享同样的管道名,但是每个实例都有各自的缓存和句柄,作为一个隔离的通道,让客户端-服务器端进行通讯,这些实例允许客户端同时使用相同名字的管道。

信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

消息队列:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点

信号:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

共享内存:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

套接字:日常工作中经常遇到,此次不做介绍。

方式有很多,目前为止只用到过套接字,在时间有限的情况下自己仅选择命名管道进行学习。

命名管道,上面也介绍了很多,它是相对于匿名管道来说的。由于是初次学习,是学习而不是为了完成项目需求,所以本着实现最基本的框架即可的原则来进行下面讲述。

命名管道有两个很重要的类:

NamedPipeClientStream:公开命名管道周围的 System.IO.Stream,该管道既支持同步读写操作,也支持异步读写操作。

NamedPipeServerStream:公开命名管道周围的 System.IO.Stream,该管道既支持同步读写操作,也支持异步读写操作。

从上面的定义也可看出client和server定义相同,因此其通信角色也可互换。同时其定义也正对应着其字面意思。有点拗口,简单来说无非就是定义有名字的管道周围的stream。多余的不说了

参考代码:

Server端:

Thread receiveDataThread = new Thread(new ThreadStart(ReceiveDataFromClient));

private static void ReceiveDataFromClient()
{
while (true)
{
try
{
NamedPipeServerStream pipeServer = new NamedPipeServerStream("closePipe", PipeDirection.InOut, );
pipeServer.WaitForConnection();
StreamReader sr = new StreamReader(pipeServer);
string receiveData = sr.ReadLine();
Thread.Sleep();
sr.Close(); Console.WriteLine("[server] receive {0} from client", receiveData);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}

client端:

private static void SendDataToServer()
{
try
{
NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "closePipe", PipeDirection.InOut, PipeOptions.Asynchronous);
pipeClient.Connect();
StreamWriter sw = new StreamWriter(pipeClient);
sw.WriteLine("hello,everyone");
sw.Flush();
Thread.Sleep();
sw.Close(); Console.WriteLine("[client] send hello,everyone to server");
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

windows服务的创建、安装、调试全过程及引发的后续学习的更多相关文章

  1. windows service 的创建 安装 调试 错误回发

    关于如何快速创建一个windows服务 1.在vs中创建windows服务 名称:你要写的服务名称 位置:创建服务所在的位置 点击确定 2.代码编写 3.添加安装程序 点击添加安装程序出现 分别右击设 ...

  2. C# windows服务的创建与调试

    Windows Service这一块并不复杂,但是注意事项太多了,网上资料也很凌乱,偶尔自己写也会丢三落四的.所以本文也就产生了,本文不会写复杂的东西,完全以基础应用的需求来写,所以不会对Window ...

  3. 【转】C# windows服务的创建与调试

    Windows Service这一块并不复杂,但是注意事项太多了,网上资料也很凌乱,偶尔自己写也会丢三落四的.所以本文也就产生了,本文不会写复杂的东西,完全以基础应用的需求来写,所以不会对Window ...

  4. C# Windows服务的创建、安装、调试

    一.查看已有的Windows服务 选择菜单"开始"-〉"控制面板"-〉"管理工具"-〉"服务"来查看现有系统中的服务 二 ...

  5. C# Windows Service服务的创建和调试

    前言 关于Windows服务创建和调试的文章在网络上的很多文章里面都有,直接拿过来贴在这里也不过仅仅是个记录,不会让人加深印象.所以本着能够更深刻了解服务项目的创建和调试过程及方法的目的,有了这篇记录 ...

  6. 关于windows服务的编写/安装/与调试

    前注: 首先,这篇文章是从网上转过来的,因为最近有个项目,需要编写一个Windows Service来定时执行程序,网上很容易找到了这篇文章,大概看了一下,文章讲的还是很详细的.不过这篇文章应该是.n ...

  7. 玩转Windows服务系列——创建Windows服务

    创建Windows服务的项目 新建项目->C++语言->ATL->ATL项目->服务(EXE) 这样就创建了一个Windows服务项目. 生成的解决方案包含两个项目:Servi ...

  8. 玩转Windows服务系列——创建Windows服务

    原文:玩转Windows服务系列——创建Windows服务 创建Windows服务的项目 新建项目->C++语言->ATL->ATL项目->服务(EXE) 这样就创建了一个Wi ...

  9. windows服务的创建、安装和调试

    1.创建 windows服务 项目   文件 -> 新建项目 -> 已安装的模板 -> Visual C# -> windows ,在右侧窗口选择"windows 服 ...

随机推荐

  1. ACM:统计难题 解题报告-字典树(Trie树)

    统计难题 Time Limit:2000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status ...

  2. dom事件不求甚解,色解事件捕获和冒泡

    以前对事件只会用jq的bind绑定一下,脑海里留着书中的事件循环,一直认为事件就是这儿循环的,最近看园子里的文章,对事件的了解更模糊了 所以我做了个小实验,总结一下看的这些零零碎碎的文章,如果总结错了 ...

  3. Resharp最新破解方法

    ReSharper是一个JetBrains公司出品的著名的代码生成工具,其能帮助Microsoft Visual Studio成为一个更佳的IDE.它包括一系列丰富的能大大增加C#和Visual Ba ...

  4. [LintCode] LRU Cache 缓存器

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...

  5. [LintCode] House Robber III 打家劫舍之三

    The thief has found himself a new place for his thievery again. There is only one entrance to this a ...

  6. [转载]How To Add Swap on Ubuntu 12.04

    How To Add Swap on Ubuntu 12.04 Aug 17, 2012  Linux Basics Ubuntu   About Linux Swapping Linux RAM i ...

  7. mysql破解root用户密码总结

    方法一: 1. /etc/my.cnf 在[mysqld]段中加入 skip-grant-table2. 重启mysql3. 直接mysql登录4. 通过修改权限表方式修改mysql密码(update ...

  8. ArcGIS JavaScript API异常之onExtentChange事件覆盖onClick事件

    利用Esri官方提供的聚合类进行聚合,由于数据较多,为了加快速度,在聚合之前对当期范围进行判断,如果不在当前视图范围的,就不聚合了. 所以,由于Esri官方的类是监听了zoomEnd事件,如下代码 t ...

  9. HTML静态网页 Window.document对象

    一.找到元素: docunment.getElementById("id"):根据id找,最多找一个:    var a =docunment.getElementById(&qu ...

  10. Web安全学习笔记之一

    浏览器基本策略:同源策略 同源策略规定:不同域的客户端脚本在没有明确授权的情况下,不能读写对方的资源. 同域与不同域:如http://www.text.com与https://www.text.com ...