/// <summary> /// 发送邮件前检查需要设置的信息是否完整,收集 错误 信息 /// </summary> /// <param name="dicMsg">将检查信息收集到此集合</param> private void InnerCheckSendMail4Error(Dictionary <MailInfoType, string> dicMsg) { #region 处理 发件/收件 if (string.IsNullOrEmpty(From)) { From = "*****@*****.**"; FromDisplayName = "h3bpm"; } else { if (!MailValidatorHelper.IsEmail(From)) { string strTemp = string.Format(MailInfoHelper.GetMailInfoStr(MailInfoType.FromFormat), FromDisplayName, From); dicMsg.Add(MailInfoType.FromFormat, strTemp); } } if (string.IsNullOrEmpty(To)) { dicMsg.Add(MailInfoType.ToEmpty, MailInfoHelper.GetMailInfoStr(MailInfoType.ToEmpty)); } else { foreach (var item in To.Split(';')) { if (!MailValidatorHelper.IsEmail(item)) { string strTemp = string.Format(MailInfoHelper.GetMailInfoStr(MailInfoType.ToFormat), item, item); dicMsg.Add(MailInfoType.ToFormat, strTemp); } } } #endregion 处理 发件/收件 // SmtpClient 实例未设置 if (m_SmtpClient == null) { dicMsg.Add(MailInfoType.SmtpClientEmpty, MailInfoHelper.GetMailInfoStr(MailInfoType.SmtpClientEmpty)); } else { // SMTP 主服务器设置 (默认端口为25) if (m_SmtpClient.Host.Length == 0) { dicMsg.Add(MailInfoType.HostEmpty, MailInfoHelper.GetMailInfoStr(MailInfoType.HostEmpty)); } // SMPT 凭证 if (m_SmtpClient.EnableSsl && m_SmtpClient.ClientCertificates.Count == 0) { dicMsg.Add(MailInfoType.CertificateEmpty, MailInfoHelper.GetMailInfoStr(MailInfoType.CertificateEmpty)); } } }
/// <summary> /// 发送邮件前检查需要设置的信息是否完整,收集 提示 信息 /// </summary> /// <param name="dicMsg">将检查信息收集到此集合</param> private void InnerCheckSendMail4Info(Dictionary <MailInfoType, string> dicMsg) { #region 处理 抄送/密送 Cc = Cc ?? ""; Bcc = Bcc ?? ""; #endregion 处理 抄送/密送 // 邮件主题 if (Subject.Length == 0) { dicMsg.Add(MailInfoType.SubjectEmpty, MailInfoHelper.GetMailInfoStr(MailInfoType.SubjectEmpty)); } // 邮件内容 if (Body.Length == 0 && (Attachments == null || (Attachments != null && Attachments.Count == 0)) ) { dicMsg.Add(MailInfoType.BodyEmpty, MailInfoHelper.GetMailInfoStr(MailInfoType.BodyEmpty)); } }
private void InnerSendMessageSync() { var msg = CheckSendMail(); if (msg.Count > 0) { throw new FormatException(MailInfoHelper.GetMailInfoStr(msg)); } try { var mMailMessage = CreateMessagex(); #region 异步发送邮件 if (PrepareSendCount == 1) { // 情况一:不重用 SmtpClient 实例会将PrepareSendCount设置为1 // 情况二:计划发送只有一条 m_SmtpClient.SendAsync(mMailMessage, AsycUserState); if (m_autoDisposeSmtp) { m_SmtpClient = null; } } else { // 情况一:重用 SmtpClient 逻辑,即我们可以直接操作全局的 m_SmtpClient // 情况二:批量发送邮件 PrepareSendCount>1 // 情况三:PrepareSendCount 还未设置,为0。比如场景在循环中做些判断,再决定发邮件,循环完才调用 SetBatchMailCount 设置计划邮件数量 MailUserState state = new MailUserState() { AutoReleaseSmtp = m_autoDisposeSmtp, CurMailMessage = mMailMessage, CurSmtpClient = m_SmtpClient, UserState = AsycUserState, }; MessageQueue.Enqueue(state); Interlocked.Increment(ref m_messageQueueCount); if (m_SendMailThread == null) { m_SendMailThread = new Thread(() => { // noItemCount 次获取不到元素,就抛出线程异常 int noItemCount = 0; while (true) { if (PrepareSendCount != 0 && PrepareSendCount == CompletedSendCount) { // 已执行完毕。 this.AutoDisposeSmtp(); break; } else { MailUserState curUserState = null; if (!MessageQueue.IsEmpty) { //#if DEBUG // Debug.WriteLine("WaitOne" + Thread.CurrentThread.ManagedThreadId); //#endif // 当执行异步取消时,会清空MessageQueue,所以 WaitOne 必须在从MessageQueue中取到元素之前 AutoResetEvent.WaitOne(); if (MessageQueue.TryDequeue(out curUserState)) { Interlocked.Decrement(ref m_messageQueueCount); m_SmtpClient.SendAsync(curUserState.CurMailMessage, curUserState); } } else { if (noItemCount >= 10) { // 没有正确设置 PrepareSendCount 值。导致已没有邮件但此线程出现死循环 this.InnerDisposeSmtp(); throw new Exception(MailValidatorHelper.EMAIL_PREPARESENDCOUNT_NOTSET_ERROR); } Thread.Sleep(1000); noItemCount++; } } // SmtpClient 为null表示异步预计发送邮件数已经发送完,在 OnSendCompleted 进行了 m_SmtpClient 释放 if (m_SmtpClient == null) { break; } } m_SendMailThread = null; }); m_SendMailThread.Start(); } } #endregion 异步发送邮件 } catch (Exception e) { throw new FormatException(e.Message); } }
/// <summary> /// 发送Email /// </summary> private void InnerSendMessage() { bool hasError = false; var msg = CheckSendMail(); if (msg.Count > 0) { throw new FormatException(MailInfoHelper.GetMailInfoStr(msg)); } var mMailMessage = CreateMessagex(); if (!hasError) { if (m_IsAsync) { #region 异步发送邮件 if (PrepareSendCount == 1) { // 情况一:不重用 SmtpClient 实例会将PrepareSendCount设置为1 // 情况二:计划发送只有一条 // PrepareSendCount 是发送单条邮件。 MailUserState state = new MailUserState() { AutoReleaseSmtp = m_autoDisposeSmtp, CurMailMessage = mMailMessage, CurSmtpClient = m_SmtpClient, IsSmpleMail = true, UserState = AsycUserState, }; if (m_autoDisposeSmtp) { // 由发送完成回调函数根据 IsSmpleMail 字段进行释放 m_SmtpClient = null; } ThreadPool.QueueUserWorkItem((userState) => { // 无需 catch 发送异常,因为是异步,所以这里 catch 不到。 MailUserState curUserState = userState as MailUserState; curUserState.CurSmtpClient.SendAsync(mMailMessage, userState); }, state); } else { // 情况一:重用 SmtpClient 逻辑,即我们可以直接操作全局的 m_SmtpClient // 情况二:批量发送邮件 PrepareSendCount>1 // 情况三:PrepareSendCount 还未设置,为0。比如场景在循环中做些判断,再决定发邮件,循环完才调用 SetBatchMailCount 设置计划邮件数量 MailUserState state = new MailUserState() { AutoReleaseSmtp = m_autoDisposeSmtp, CurMailMessage = mMailMessage, CurSmtpClient = m_SmtpClient, UserState = AsycUserState, }; MessageQueue.Enqueue(state); Interlocked.Increment(ref m_messageQueueCount); if (m_SendMailThread == null) { m_SendMailThread = new Thread(() => { // noItemCount 次获取不到元素,就抛出线程异常 int noItemCount = 0; while (true) { if (PrepareSendCount != 0 && PrepareSendCount == CompletedSendCount) { // 已执行完毕。 this.AutoDisposeSmtp(); break; } else { MailUserState curUserState = null; if (!MessageQueue.IsEmpty) { //#if DEBUG // Debug.WriteLine("WaitOne" + Thread.CurrentThread.ManagedThreadId); //#endif // 当执行异步取消时,会清空MessageQueue,所以 WaitOne 必须在从MessageQueue中取到元素之前 AutoResetEvent.WaitOne(); if (MessageQueue.TryDequeue(out curUserState)) { Interlocked.Decrement(ref m_messageQueueCount); m_SmtpClient.SendAsync(curUserState.CurMailMessage, curUserState); } } else { if (noItemCount >= 10) { // 没有正确设置 PrepareSendCount 值。导致已没有邮件但此线程出现死循环 this.InnerDisposeSmtp(); throw new Exception(MailValidatorHelper.EMAIL_PREPARESENDCOUNT_NOTSET_ERROR); } Thread.Sleep(1000); noItemCount++; } } // SmtpClient 为null表示异步预计发送邮件数已经发送完,在 OnSendCompleted 进行了 m_SmtpClient 释放 if (m_SmtpClient == null) { break; } } m_SendMailThread = null; }); m_SendMailThread.Start(); } } #endregion 异步发送邮件 } else { #region 步发送邮件 try { m_SmtpClient.Send(mMailMessage); m_CompletedSendCount++; } catch (ObjectDisposedException smtpDisposedEx) { throw smtpDisposedEx; } catch (InvalidOperationException smtpOperationEx) { throw smtpOperationEx; } catch (SmtpFailedRecipientsException smtpFailedRecipientsEx) { throw smtpFailedRecipientsEx; } catch (SmtpException smtpEx) { throw smtpEx; } finally { if (mMailMessage != null) { InnerDisposeMessage(mMailMessage); mMailMessage = null; } AutoDisposeSmtp(); } #endregion 步发送邮件 } } }