C#写的一个Windows服务,没效果~~~~~~

Hertz_liu 2009-02-01 01:38:04
新年第一问,先祝大家在新的一年里万事如意~~~~~
问题如下 :
我用C#写了一个Windows服务,想实现的功能就是每隔一秒钟,检测数据库邮件队列表中有无新数据加入,如果有,执行发邮件的操作
服务中的主要代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Data.SqlClient;
using System.Net.Mail;

namespace WindowsService_CheckNewRecord
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
// TODO: 在此处添加代码以启动服务。
timer1.Start();//timer1是一个计时器,是从工具箱的组件中拖的
}

protected override void OnStop()
{
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
}

private void timer1_Tick(object sender, EventArgs e)
{
string strConn = "连接数据库的字符串";
SqlConnection sqlcon = new SqlConnection(strConn);
string strAdp = "select * from tb_mail where DeletedTime is null";//tb_mail表结构(收件人地址,邮件主题,邮件内容,删除时间)
SqlDataAdapter sqladp = new SqlDataAdapter(strAdp,sqlcon);
DataSet ds = new DataSet();
sqladp.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
string toEmail = ds.Tables[0].Rows[i]["ToEmail"].ToString();
string topic = ds.Tables[0].Rows[i]["Topic"].ToString();
string body = ds.Tables[0].Rows[i]["Body"].ToString();
SendEmail(toEmail,topic,body);//调用下面的函数

//发送完成后,把当前系统时间写入DeletedTime字段
DateTime now = System.DateTime.Now;
string strCmd = "update tb_mail set DeletedTime='"+now+"' where ToEmail='"+toEmail+"'";
SqlCommand sqlcmd = new SqlCommand(strCmd, sqlcon);
sqlcmd.ExecuteNonQuery();
}
}
}

//执行发送电子邮件的操作
private void SendEmail(string toEmail, string topic, string body)
{
MailAddress from = new MailAddress("发件人电子邮件地址");
MailAddress to = new MailAddress(toEmail);
MailMessage message = new MailMessage(from, to);
message.Subject = topic;
message.IsBodyHtml = true;
message.Body = body;
SmtpClient sc = new SmtpClient("邮件服务器名称");
sc.Credentials = new System.Net.NetworkCredential("发件人电子邮件地址", "发件人电子邮件的密码");
sc.Send(message);
}
}
}


我再说一下我创建服务的步骤:
1. 新建一个项目
2. 从一个可用的项目模板列表当中选择Windows服务
3. 设计器会以设计模式打开
4. 从工具箱的组件表当中拖动一个Timer对象到这个设计表面上 (注意: 要确保是从组件列表而不是从Windows窗体列表当中使用Timer)
5. 设置Timer属性,Interval属性1000毫秒(1秒进行1次数据库操作)
6. 然后为这个服务填加功能
7.双击这个Timer,然后在里面写一些数据库操作的代码,如上Timer1_Tick事件中的代码
8. 将这个服务程序切换到设计视图
9. 右击设计视图选择“添加安装程序”
10. 切换到刚被添加的ProjectInstaller的设计视图
11. 设置serviceInstaller1组件的属性:
1) ServiceName = WindowsServer_CheckNewRecord
2) StartType = Automatic (开机自动运行)
12. 设置serviceProcessInstaller1组件的属性 Account = LocalSystem
13. 改变路径到你项目所在的bin\Debug文件夹位置(如果你以Release模式编译则在bin\Release文件夹)
14. 执行命令“InstallUtil.exe MyWindowsService.exe”注册这个服务,使它建立一个合适的注册项。(InstallUtil这个程序在WINDOWS文件夹\Microsoft.NET\Framework\v1.1.4322下面)
15. 右击桌面上“我的电脑”,选择“管理”就可以打计算机管理控制台
16. 在“服务和应用程序”里面的“服务”部分里,右击新建的服务启动即可了


但现在问题是,我代码如果放在别处,用一个Timer,能够实现我要的效果,但是写成这样的服务以后,就一点反应也没有了,不能实现我想实现的功能,各个高手,帮我看看问题出在哪里?(问题篇幅有点长,请见谅~~~~~)
...全文
559 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hertz_liu 2009-02-04
  • 打赏
  • 举报
回复
感謝各位的回帖~~~~~~~~~~~~~~~~~~~~~~~~
d15212380 2009-02-02
  • 打赏
  • 举报
回复
真的好棒啊。不错
bluedodo 2009-02-02
  • 打赏
  • 举报
回复
延迟线程的操作是不是会消耗不必要的系统资源?
haihaomeiyou1 2009-02-02
  • 打赏
  • 举报
回复
赞一个,谢谢楼主了。
miqier 2009-02-02
  • 打赏
  • 举报
回复
如果要使用Timer,需要注意一个问题,楼主用的Timer是Form控件,在Windows服务中是不生效的,需要使用System.Timers.Timer控件。
可以手动生成这个控件。

System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed +=new System.Timers.ElapsedEventHandler(timer_Elapsed);

Hertz_liu 2009-02-02
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 chagel 的回复:]
好奇地问一下,楼主为什么不用sql mail加上sql agent来做?
一个存储过程一个调度task很方便地就能省事了
[/Quote]
前辈,如何做,能说得具体一些吗?
Hertz_liu 2009-02-02
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 net_lover 的回复:]
你应当使用
System.Threading.Timer
或者
System.Timers.Timer
而不是
System.Windows.Forms.Timer

你在工具箱里加入的是System.Windows.Forms.Timer 吧
[/Quote]
是的,从工具箱里拖的是System.Windows.Forms.Timer,但是后来我换成了System.Timers.Timer。可是还是没用
chagel 2009-02-02
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 liu2008hz 的回复:]
引用 20 楼 chagel 的回复:
好奇地问一下,楼主为什么不用sql mail加上sql agent来做?
一个存储过程一个调度task很方便地就能省事了

前辈,如何做,能说得具体一些吗?
[/Quote]
前辈不敢当..
根据我对你描述的理解,需求是:
定时发送邮件给数据表里的邮件地址。

很简单的,比如,下面这个SP会根据birthdays表中的数据(生日,邮件地址)发送生日祝福:

CREATE TABLE dbo.birthdays
(
fullname VARCHAR(128),
email VARCHAR(128),
birthdate SMALLDATETIME
)
GO

INSERT birthdays VALUES('AB', 'ab@nonexists.com', '19740201')
INSERT birthdays VALUES('CB', 'cb@nonexists.com', '19870123')
INSERT birthdays VALUES('TC', 'tc@nonexists.com', '20011227')
GO

-- and include your own address, with today's date, for testing!
CREATE PROCEDURE dbo.proc_happyBirthday
AS
BEGIN
SET NOCOUNT ON
DECLARE @BCCList VARCHAR(8000)
SET @BCCList = ''

SELECT @BCCList = @BCCList + ';' + COALESCE(email, '')
FROM Birthdays
WHERE
MONTH(birthdate) = MONTH(GETDATE())
AND DAY(birthdate) = DAY(GETDATE())

SET @BCCList = SUBSTRING(@BCCList, 2, LEN(@BCCList))

EXEC master..xp_smtp_sendmail
@TO = 'you@you.com',
@BCC = @BCCList,
@from = 'someone@somewhere.com',
@subject = 'Happy Birthday to you!',
@message = 'You belong in a zoo!',
@server = 'smtp.yourdomain.com'
END
GO


定时运行存储过程,可以利用SQL Server的Agent服务。很方便,新建一个job选择数据库和T-SQL类型任务,执行SP就可以了。如果有问题,可以参考MSDN有关Agent的介绍(相信不会有问题啦:))

这个方案在SQL2k,2k5,2k8都可以,2k5、8用Database Mail取代了SQL Mail,你需要在Surface Area里面启用SQL Mail,以及Agent服务。

可能有用的参考:
http://classicasp.aspfaq.com/email/how-do-i-send-e-mail-from-sql-server.html
http://support.microsoft.com/kb/263556
snailrain 2009-02-02
  • 打赏
  • 举报
回复
up
chagel 2009-02-01
  • 打赏
  • 举报
回复
好奇地问一下,楼主为什么不用sql mail加上sql agent来做?
一个存储过程一个调度task很方便地就能省事了
delphi_new 2009-02-01
  • 打赏
  • 举报
回复
用system.timers.timer 但是这样在INTEVAL其间处理时间函数没完成的话会在下一次事件间隔再次调用该事件函数,慎用
vb_help 2009-02-01
  • 打赏
  • 举报
回复
timer 有3种
system.windows.Forms(可以拖拽)
System.Timers.Timer(手动添加 可以改用这个试试)
System.Threading.Timer
aboluoyuren 2009-02-01
  • 打赏
  • 举报
回复
timer1.ennable=true;
即可
  • 打赏
  • 举报
回复
timer 有N多种,不同的Timer功能和函数有差别,看看你用的哪个吧。。。
孟子E章 2009-02-01
  • 打赏
  • 举报
回复
你应当使用
System.Threading.Timer
或者
System.Timers.Timer
而不是
System.Windows.Forms.Timer

你在工具箱里加入的是System.Windows.Forms.Timer 吧

wuyq11 2009-02-01
  • 打赏
  • 举报
回复
通过线程延迟操作
空心兜兜 2009-02-01
  • 打赏
  • 举报
回复
学习下,思路不错
小菲1215 2009-02-01
  • 打赏
  • 举报
回复
不要用timer,用sleep还更好些,把代码执行的东西写入系统日志里面
  • 打赏
  • 举报
回复
回帖是一种美德 mark
homesos 2009-02-01
  • 打赏
  • 举报
回复
就不要用timer了,直接用while(条件){sleep(1000);},虽然不精确,应该不会影响。

可以在代码中写日志到windows日志,看看程序是否有运行,运行到何处,什么状态。
加载更多回复(9)

62,268

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧