我正在努力创建一个Windows服务,该服务会在客户提交过期后的一个月内向客户发送电子邮件。我在Visual Studios 2008中使用vb.net
因为它是一个Windows服务,所以很难调试。试图缩小我的错误我创建了一个“sendDebugEmail”方法,如果它到达某一行,它会向我发送一封电子邮件。电子邮件永远不会超过“dr = cmd.ExecuteReader()”
我想知道我做错了什么。我的SQL语句应该可以正常工作。我在我的SQL服务器数据库中测试过它。
我创建了一个我刚刚在sql server中创建的dummy_database。我为那里的虚拟表添加了一个INSERT sql语句,只是为了看看我是否可以实际访问数据库。所有表格都是行号和发送时间。当我运行我的Windows服务时,数据库更新就好了。
任何帮助将不胜感激。感谢
Dim conn As New SqlConnection(connString2)
sendDebugEmail("134")
SQL = "Select email FROM _Customer WHERE custID in (SELECT custID FROM _OnlineCustomer WHERE ExpirationDate <= '6-20-12' AND ExpirationDate >= '6-10-12')"
Dim cmd As New SqlCommand(SQL, conn)
sSubject = "hello"
sBody = "This is test data"
Dim dr As SqlDataReader
sendDebugEmail("143")
Try
dr = cmd.ExecuteReader() // This is were it stops
sendDebugEmail("147")
While dr.Read
sendDebugEmail("152")
Try
LogInfo("Service woke up")
Dim i As Integer = 0
' Prepare e-mail fields
sFrom = "test@gmail.com"
sTo = "test1@gmail.com"
sCc = "test2@gmail.com"
Dim oMailMsg As MailMessage = New MailMessage
oMailMsg.From = sFrom
oMailMsg.To = sTo
oMailMsg.Cc = sCc
' Call a stored procedure to process the current item
' The success message
oMailMsg.Subject = sSubject + "(Success)"
oMailMsg.Body = sBody + "Email has been sent successfully."
' Send the message
If Not (oMailMsg.To = String.Empty) Then
SmtpMail.Send(oMailMsg)
End If
Catch obug As Exception
LogEvent(obug.Message)
Finally
End Try
End While
Catch ex As Exception
Finally
dr.Close()
cmd.Dispose()
conn.Close()
conn.Dispose()
End Try
End Sub
/////////////////////////////////////////////// //////////////////////////////////
解决问题:我建立了连接,但我从未打开它。
我需要conn.open()
最能帮助我的是将此代码添加到我的上一个catch语句中:
sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)
它向我发送了一封stackTrace的电子邮件,并且非常容易调试
答案 0 :(得分:2)
您是否诱捕和吞咽异常?如果你是,停下来。让异常服务使服务崩溃:异常将记录在事件日志中。您应该捕获的唯一例外是您可以实际恢复的那些(尽管它有效以捕获异常,记录并通过throw;
重新抛出它)。
您是否使用log4net(http://logging.apache.org/log4net/)或类似内容对您的代码进行了检测?您应该(特别是对于像Windows服务这样的守护进程) - 您(或操作)如何在发生时(如他们所愿)诊断服务问题。
编辑注:
您应该使用using
语句:所有这些ADO.Net对象都是IDisposable
。它使代码更清晰。
考虑使用SqlDataAdapter用结果集填充DataTable或DataSet。你正在使用的模式:
read a row from SQL
while read was successful
send an email
read a row from SQL
最终会导致数据库阻塞。与邮件服务器通信可能会导致高延迟。如果邮件服务器没有应答,或者您遇到网络拥塞或其他任何原因,那么在发送邮件或由于超时而引发异常之前,您将一直处于挂起状态。并且你的SQL查询将坐在那里,桌面上有读锁和你正在读取数据的索引,阻止尝试进行更新,插入或删除的人。你的生产DBA会很烦恼。您希望保持锁定移动并尽快释放锁定。
答案 1 :(得分:1)
如果您确定您的代码(没有例外),我认为您应检查您用于连接SQL服务器的身份验证(在app.config文件/内联中的连接字符串内) Windows服务的代码。)
如果您正在使用SQL身份验证(检查用户名 sa 的连接字符串及其密码),则将Windows服务的帐户类型设置为 LocalService 将有助于您。
如果SQL连接使用的是Windows身份验证,那么将Windows服务的帐户类型设置为 LocalSystem 会对您有所帮助。
帐户类型修改也可以在安装后完成。为此,请转到控制面板 - &gt;管理工具 - &gt;服务 - &gt; YourService ,右键单击并选择属性 - >登录并在那里执行。如果您选择LocalSystem(Windows身份验证),系统将要求您输入运行该服务的帐户的登录凭据。
对于SQL连接中的Windows身份验证,运行服务的帐户的凭据也将用于SQL连接。
希望这会有所帮助......
答案 2 :(得分:0)
另一个建议是在你的过程启动时给你一个睡眠声明,所以oyu有时间附加它
答案 3 :(得分:0)
问题已解决:我设置了连接,但我从未打开过它 我需要conn.open()
最能帮助我的是将此代码添加到我的上一个catch语句中:
sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)
它向我发送了一封stackTrace的电子邮件,并且非常容易调试