asp.net 异步群发邮件时遭遇到的问题
客户要求为他的网站注册用户群发邮件
网站注册用户有9860名,因为注册时需要用户必须提供电子邮件,因为要对所有的9860名用户发送
如果采用主线程发送,必然造成连接超时或是漫长的用户等待,因而采用了异步发送的方式处理此群发
于是最初写了一个群发的类
网站注册用户有9860名,因为注册时需要用户必须提供电子邮件,因为要对所有的9860名用户发送
如果采用主线程发送,必然造成连接超时或是漫长的用户等待,因而采用了异步发送的方式处理此群发
于是最初写了一个群发的类
Code
群发邮件处理类#Region "群发邮件处理类"
/**/''' <summary>
''' 邮件群发异步处理类
''' </summary>
<Serializable()> _
Public Class BulkMailClass BulkMail
Private _maxCount As Integer = 0
Private _currentCount As Integer = 0
Private _runState As BulkMailRunState = BulkMailRunState.Unkonw
Private _message As String
Private _list As List(Of Entity.Member.OwnerIdentityEntity)
Private _thread As Threading.Thread
Private _mailSubject As String
Private _mailBody As String
Private _config As Web.Config.WebConfig
/**/''' <summary>
''' 创建一个邮件群发实例 <see cref="BulkMail" />
''' </summary>
''' <param name="subject">邮件主题</param>
''' <param name="body">邮件内容</param>
Public Sub New()Sub New(ByVal subject As String, ByVal body As String)
_config = Web.Config.WebConfig.GetConfig
_mailSubject = subject
_mailBody = body
End Sub
/**/''' <summary>
''' 初始化发送事件
''' </summary>
''' <param name="list">信息集合</param>
Public Sub Send()Sub Send(ByVal list As List(Of Entity.Member.OwnerIdentityEntity))
_list = list
_thread = New Threading.Thread(New Threading.ThreadStart(AddressOf Me.SendMail))
_thread.Start()
End Sub
/**/''' <summary>
''' 异步发送邮件
''' </summary>
Private Sub SendMail()Sub SendMail()
Try
_message = "群发开始"
_runState = BulkMailRunState.Run
_currentCount = 0
_maxCount = _list.Count
Dim mail As Web.Mail.Mail
mail = New Web.Mail.Mail
mail.From = _config.SmtpEmail
mail.FromName = _config.SiteName
mail.isHtml = True
mail.Priority = "high"
mail.Subject = _mailSubject
mail.Body = _mailBody
Dim smtp As Web.Mail.SmtpMail
smtp = New Web.Mail.SmtpMail
smtp.chkSmtp = _config.SmtpAuth
smtp.smtpPassWord = _config.SmtpLoginPassword
smtp.SmtpPort = _config.SmtpPort
smtp.SmtpServer = _config.SmtpServer
smtp.smtpUserName = _config.SmtpLoginName
For Each info As Entity.Member.OwnerIdentityEntity In _list
_currentCount += 1
If info.Email IsNot Nothing AndAlso info.Email.Contains("@") Then
mail.Recipient.Add(info.Email)
_message = String.Format("正在给{0}发送邮件", info.RealName)
_runState = BulkMailRunState.Run
mail.Subject = _mailSubject
mail.Body = _mailBody
smtp.Send(mail)
mail.Recipient.Clear()
End If
Next
_runState = BulkMailRunState.Over
_message = "群发结束"
Catch ex As Exception
_runState = BulkMailRunState.Error
_message = ex.Message & ex.Source & ex.ToString & ex.InnerException.ToString
End Try
End Sub
自定义属性#Region "自定义属性"
/**/''' <summary>
''' 群发状态
''' </summary>
''' <value>The state of the run.</value>
Public ReadOnly Property RunState()Property RunState() As BulkMailRunState
Get
Return _runState
End Get
End Property
/**/''' <summary>
''' 群发邮件总数
''' </summary>
''' <value>The max count.</value>
Public ReadOnly Property MaxCount()Property MaxCount() As Integer
Get
Return _maxCount
End Get
End Property
/**/''' <summary>
''' 已发送数量
''' </summary>
''' <value>The current count.</value>
Public ReadOnly Property CurrentCount()Property CurrentCount() As Integer
Get
Return _currentCount
End Get
End Property
/**/''' <summary>
''' 附加的信息
''' </summary>
''' <value>The message.</value>
Public ReadOnly Property Message()Property Message() As String
Get
Return _message
End Get
End Property
#End Region
End Class
群发邮件处理类#Region "群发邮件处理类"
/**/''' <summary>
''' 邮件群发异步处理类
''' </summary>
<Serializable()> _
Public Class BulkMailClass BulkMail
Private _maxCount As Integer = 0
Private _currentCount As Integer = 0
Private _runState As BulkMailRunState = BulkMailRunState.Unkonw
Private _message As String
Private _list As List(Of Entity.Member.OwnerIdentityEntity)
Private _thread As Threading.Thread
Private _mailSubject As String
Private _mailBody As String
Private _config As Web.Config.WebConfig
/**/''' <summary>
''' 创建一个邮件群发实例 <see cref="BulkMail" />
''' </summary>
''' <param name="subject">邮件主题</param>
''' <param name="body">邮件内容</param>
Public Sub New()Sub New(ByVal subject As String, ByVal body As String)
_config = Web.Config.WebConfig.GetConfig
_mailSubject = subject
_mailBody = body
End Sub
/**/''' <summary>
''' 初始化发送事件
''' </summary>
''' <param name="list">信息集合</param>
Public Sub Send()Sub Send(ByVal list As List(Of Entity.Member.OwnerIdentityEntity))
_list = list
_thread = New Threading.Thread(New Threading.ThreadStart(AddressOf Me.SendMail))
_thread.Start()
End Sub
/**/''' <summary>
''' 异步发送邮件
''' </summary>
Private Sub SendMail()Sub SendMail()
Try
_message = "群发开始"
_runState = BulkMailRunState.Run
_currentCount = 0
_maxCount = _list.Count
Dim mail As Web.Mail.Mail
mail = New Web.Mail.Mail
mail.From = _config.SmtpEmail
mail.FromName = _config.SiteName
mail.isHtml = True
mail.Priority = "high"
mail.Subject = _mailSubject
mail.Body = _mailBody
Dim smtp As Web.Mail.SmtpMail
smtp = New Web.Mail.SmtpMail
smtp.chkSmtp = _config.SmtpAuth
smtp.smtpPassWord = _config.SmtpLoginPassword
smtp.SmtpPort = _config.SmtpPort
smtp.SmtpServer = _config.SmtpServer
smtp.smtpUserName = _config.SmtpLoginName
For Each info As Entity.Member.OwnerIdentityEntity In _list
_currentCount += 1
If info.Email IsNot Nothing AndAlso info.Email.Contains("@") Then
mail.Recipient.Add(info.Email)
_message = String.Format("正在给{0}发送邮件", info.RealName)
_runState = BulkMailRunState.Run
mail.Subject = _mailSubject
mail.Body = _mailBody
smtp.Send(mail)
mail.Recipient.Clear()
End If
Next
_runState = BulkMailRunState.Over
_message = "群发结束"
Catch ex As Exception
_runState = BulkMailRunState.Error
_message = ex.Message & ex.Source & ex.ToString & ex.InnerException.ToString
End Try
End Sub
自定义属性#Region "自定义属性"
/**/''' <summary>
''' 群发状态
''' </summary>
''' <value>The state of the run.</value>
Public ReadOnly Property RunState()Property RunState() As BulkMailRunState
Get
Return _runState
End Get
End Property
/**/''' <summary>
''' 群发邮件总数
''' </summary>
''' <value>The max count.</value>
Public ReadOnly Property MaxCount()Property MaxCount() As Integer
Get
Return _maxCount
End Get
End Property
/**/''' <summary>
''' 已发送数量
''' </summary>
''' <value>The current count.</value>
Public ReadOnly Property CurrentCount()Property CurrentCount() As Integer
Get
Return _currentCount
End Get
End Property
/**/''' <summary>
''' 附加的信息
''' </summary>
''' <value>The message.</value>
Public ReadOnly Property Message()Property Message() As String
Get
Return _message
End Get
End Property
#End Region
End Class
然后把访类的实例存储在Session会话中,在客户端刷新读取发送进度并显示,在本地测试成功,于是发布到服务器上
客户发送邮件时反馈没有出现进度条,而是直接显示群发完成,但注册会员并未收到邮件
后测试发现是因为群发类把所有的信息存储在Session中,其中也包含了所有的会员信息,由于数据量极大,造成Sesson会话变量丢失,从而造成群发操作直接结束
后修改类
Code
群发邮件处理类#Region "群发邮件处理类"
/**/''' <summary>
''' 邮件群发异步处理类
''' </summary>
<Serializable()> _
Public Class BulkMailClass BulkMail
Private _maxCount As Integer = 0
Private _currentCount As Integer = 0
Private _runState As BulkMailRunState = BulkMailRunState.Unkonw
Private _message As String
Private _thread As Threading.Thread
Private _mailSubject As String
Private _mailBody As String
Private _config As Web.Config.WebConfig
/**/''' <summary>
''' 创建一个邮件群发实例 <see cref="BulkMail" />
''' </summary>
''' <param name="subject">邮件主题</param>
''' <param name="body">邮件内容</param>
Public Sub New()Sub New(ByVal subject As String, ByVal body As String)
_config = Web.Config.WebConfig.GetConfig
_mailSubject = subject
_mailBody = body
End Sub
/**/''' <summary>
''' 初始化发送事件
''' </summary>
''' <param name="list">信息集合</param>
Public Sub Send()Sub Send(ByVal list As List(Of Entity.Member.OwnerIdentityEntity))
_thread = New Threading.Thread(AddressOf Me.SendMail)
_thread.Start(list)
End Sub
/**/''' <summary>
''' 异步发送邮件
''' </summary>
Private Sub SendMail()Sub SendMail(ByVal list As Object)
Try
Dim _list As List(Of Entity.Member.OwnerIdentityEntity) = CType(list, List(Of Entity.Member.OwnerIdentityEntity))
_message = "群发开始"
_runState = BulkMailRunState.Run
_currentCount = 0
_maxCount = _list.Count
Dim mail As Web.Mail.Mail
mail = New Web.Mail.Mail
mail.From = _config.SmtpEmail
mail.FromName = _config.SiteName
mail.isHtml = True
mail.Priority = "high"
mail.Subject = _mailSubject
mail.Body = _mailBody
Dim smtp As Web.Mail.SmtpMail
smtp = New Web.Mail.SmtpMail
smtp.chkSmtp = _config.SmtpAuth
smtp.smtpPassWord = _config.SmtpLoginPassword
smtp.SmtpPort = _config.SmtpPort
smtp.SmtpServer = _config.SmtpServer
smtp.smtpUserName = _config.SmtpLoginName
For Each info As Entity.Member.OwnerIdentityEntity In _list
_currentCount += 1
If info.Email IsNot Nothing AndAlso info.Email.Contains("@") Then
mail.Recipient.Add(info.Email)
_message = String.Format("正在给{0}发送邮件", info.RealName)
_runState = BulkMailRunState.Run
mail.Subject = _mailSubject
mail.Body = _mailBody
smtp.Send(mail)
mail.Recipient.Clear()
End If
Next
_runState = BulkMailRunState.Over
_message = "群发结束"
Catch ex As Exception
_runState = BulkMailRunState.Error
_message = ex.Message & ex.Source & ex.ToString & ex.InnerException.ToString
End Try
End Sub
自定义属性#Region "自定义属性"
/**/''' <summary>
''' 群发状态
''' </summary>
''' <value>The state of the run.</value>
Public ReadOnly Property RunState()Property RunState() As BulkMailRunState
Get
Return _runState
End Get
End Property
/**/''' <summary>
''' 群发邮件总数
''' </summary>
''' <value>The max count.</value>
Public ReadOnly Property MaxCount()Property MaxCount() As Integer
Get
Return _maxCount
End Get
End Property
/**/''' <summary>
''' 已发送数量
''' </summary>
''' <value>The current count.</value>
Public ReadOnly Property CurrentCount()Property CurrentCount() As Integer
Get
Return _currentCount
End Get
End Property
/**/''' <summary>
''' 附加的信息
''' </summary>
''' <value>The message.</value>
Public ReadOnly Property Message()Property Message() As String
Get
Return _message
End Get
End Property
#End Region
End Class
群发邮件处理类#Region "群发邮件处理类"
/**/''' <summary>
''' 邮件群发异步处理类
''' </summary>
<Serializable()> _
Public Class BulkMailClass BulkMail
Private _maxCount As Integer = 0
Private _currentCount As Integer = 0
Private _runState As BulkMailRunState = BulkMailRunState.Unkonw
Private _message As String
Private _thread As Threading.Thread
Private _mailSubject As String
Private _mailBody As String
Private _config As Web.Config.WebConfig
/**/''' <summary>
''' 创建一个邮件群发实例 <see cref="BulkMail" />
''' </summary>
''' <param name="subject">邮件主题</param>
''' <param name="body">邮件内容</param>
Public Sub New()Sub New(ByVal subject As String, ByVal body As String)
_config = Web.Config.WebConfig.GetConfig
_mailSubject = subject
_mailBody = body
End Sub
/**/''' <summary>
''' 初始化发送事件
''' </summary>
''' <param name="list">信息集合</param>
Public Sub Send()Sub Send(ByVal list As List(Of Entity.Member.OwnerIdentityEntity))
_thread = New Threading.Thread(AddressOf Me.SendMail)
_thread.Start(list)
End Sub
/**/''' <summary>
''' 异步发送邮件
''' </summary>
Private Sub SendMail()Sub SendMail(ByVal list As Object)
Try
Dim _list As List(Of Entity.Member.OwnerIdentityEntity) = CType(list, List(Of Entity.Member.OwnerIdentityEntity))
_message = "群发开始"
_runState = BulkMailRunState.Run
_currentCount = 0
_maxCount = _list.Count
Dim mail As Web.Mail.Mail
mail = New Web.Mail.Mail
mail.From = _config.SmtpEmail
mail.FromName = _config.SiteName
mail.isHtml = True
mail.Priority = "high"
mail.Subject = _mailSubject
mail.Body = _mailBody
Dim smtp As Web.Mail.SmtpMail
smtp = New Web.Mail.SmtpMail
smtp.chkSmtp = _config.SmtpAuth
smtp.smtpPassWord = _config.SmtpLoginPassword
smtp.SmtpPort = _config.SmtpPort
smtp.SmtpServer = _config.SmtpServer
smtp.smtpUserName = _config.SmtpLoginName
For Each info As Entity.Member.OwnerIdentityEntity In _list
_currentCount += 1
If info.Email IsNot Nothing AndAlso info.Email.Contains("@") Then
mail.Recipient.Add(info.Email)
_message = String.Format("正在给{0}发送邮件", info.RealName)
_runState = BulkMailRunState.Run
mail.Subject = _mailSubject
mail.Body = _mailBody
smtp.Send(mail)
mail.Recipient.Clear()
End If
Next
_runState = BulkMailRunState.Over
_message = "群发结束"
Catch ex As Exception
_runState = BulkMailRunState.Error
_message = ex.Message & ex.Source & ex.ToString & ex.InnerException.ToString
End Try
End Sub
自定义属性#Region "自定义属性"
/**/''' <summary>
''' 群发状态
''' </summary>
''' <value>The state of the run.</value>
Public ReadOnly Property RunState()Property RunState() As BulkMailRunState
Get
Return _runState
End Get
End Property
/**/''' <summary>
''' 群发邮件总数
''' </summary>
''' <value>The max count.</value>
Public ReadOnly Property MaxCount()Property MaxCount() As Integer
Get
Return _maxCount
End Get
End Property
/**/''' <summary>
''' 已发送数量
''' </summary>
''' <value>The current count.</value>
Public ReadOnly Property CurrentCount()Property CurrentCount() As Integer
Get
Return _currentCount
End Get
End Property
/**/''' <summary>
''' 附加的信息
''' </summary>
''' <value>The message.</value>
Public ReadOnly Property Message()Property Message() As String
Get
Return _message
End Get
End Property
#End Region
End Class
传送至服务器测试,成功