예제 #1
0
        /// <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));
                }
            }
        }
예제 #2
0
        /// <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));
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        /// <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  步发送邮件
                }
            }
        }