前几天做项目的时候需要用到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. awk 学习

    1. awk用例 今天用awk来统计一个字符出现的次数,总是比实际多一个.查了半天才发现问题所在. 文本tt.txt如下: <lst name="responseHeader" ...

  2. HDU2138 & 米勒拉宾模板

    题意: 给出n个数,判断它是不是素数. SOL: 米勒拉宾裸题,思想方法略懂,并不能完全理解,所以实现只能靠背模板.... 好在不是很长... Code: /*==================== ...

  3. iPad apple-touch-startup-image实现portrait和landscape

    iPad apple-touch-startup-image实现portrait和landscape 为ipad制作web应用程序的启动画面时发现个问题,只能显示竖屏图,横屏图出不来,网上的朋友都说无 ...

  4. 洛谷 P2661 信息传递 Label:并查集||强联通分量

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  5. 用存储过程 将大段的SQL藏起来

    在日常工作中,当面对比较复杂的数据库操作时不免要写一些比较长的SQL,由于某系SQL有些长(目前我写的最长的貌似有30多行吧),这时候长会面临这个   方法 优点 缺点 用"+"串 ...

  6. iOS 常用英语翻译

    1..serve advertisements within the app 服务应用中的广告.如果你的应用中集成了广告的时候,你需要勾选这一项.   √2.Attribute this app in ...

  7. iOS 发布遇到的问题 (转载)

    1.ios图片命名Icon-120.png – 120×120 iphone & ipod touch(ios7)  http://blog.csdn.net/xyxjn/article/de ...

  8. C语言与水仙花数

    C语言与水仙花数 水仙花数:前提三位数,"个位数的立方"加上"十位数的立方"加上"百位数的立方"恰好等于这个数. 我们来用C语言书写水仙花数 ...

  9. ECMAScript中关于如何获取this的定义

    文章中一些名词的翻译存疑,没有查过正式的中文名称 前面都是具体过程的解释,懒得看可以直接看获取思路 有关this的取值请移步JavaScript笔记--this的取值 获取this的过程 Runtim ...

  10. Func<T, TResult> Delegate

    public delegate TResult Func<in T, out TResult>( T arg ) http://msdn.microsoft.com/en-us/libra ...