Пример #1
0
        private void btnOk_Click(object sender, EventArgs e)
        {
            m_to      = this.txtTo.Text.Trim();
            m_cc      = this.txtCC.Text.Trim();
            m_bcc     = this.txtBcc.Text.Trim();
            m_Subject = this.txtSubject.Text.Trim();
            m_Body    = this.rtbBody.Text;

            bool isAsync = this.chbAsync.Checked;
            bool isReuse = this.cbxReuse.Checked;

            this.rtbReply.AppendText(String.Format("==============={0},{1}{2}"
                                                   , (isAsync ? "异步发送" : "同步发送"), (isReuse ? "重用SmtpClient实例" : "新SmtpClient实例"), Environment.NewLine));

            watch.Reset();
            watch.Start();

            // DateTime.Now.ToLongTimeString()
            if (this.rdoOne.Checked)
            {
                #region 实验一:单条邮件同步和异步发送(可通过添加大附件来观察同步异步效果)
                MailHelper mail = new MailHelper(isAsync);

                #region 发送单封邮件 中 加入图片链接示例。
                // 发送单封邮件 中 加入图片链接示例。
                string picPath = Environment.CurrentDirectory + "\\附件\\PIC_Mail中文.png";

                mail.AddInlineAttachment(picPath, "MyPic");

                // 注意内联图片地址写法  cid:ContentId
                m_Body = m_Body + "<br/><img src=\"cid:MyPic\" /><a href=\"cid:MyPic\" target=\"_blank\">点击在新窗口打开图片</a>";

                #endregion

                if (isAsync)
                {
                    this.SendMessageAsync(mail, true, "实验一", "单条", true, isReuse);
                }
                else
                {
                    this.SendMessage(mail, true, "实验一", "单条", true, isReuse);
                }

                #endregion
            }
            else if (this.rdoTwo.Checked)
            {
                #region 实验二:批量邮件同步和异步发送(单个线程,单个SmtpClient实例,SendAsync())

                long       count = long.Parse(this.cbbNumber.Text);
                MailHelper mail  = new MailHelper(isAsync);

                if (isReuse)
                {
                    if (isAsync)
                    {
                        for (long i = 1; i <= count; i++)
                        {
                            this.SendMessageAsync(mail, false, "实验二", "第" + i + "条", true, true);
                        }
                        mail.SetBatchMailCount(count);
                    }
                    else
                    {
                        for (long i = 1; i <= count; i++)
                        {
                            this.SendMessage(mail, false, "实验二", "第" + i + "条", true, true);
                        }
                        mail.SetBatchMailCount(count);
                    }
                }
                else
                {
                    if (isAsync)
                    {
                        for (long i = 1; i <= count; i++)
                        {
                            this.SendMessageAsync(mail, true, "实验二", "第" + i + "条", true, false);
                        }
                    }
                    else
                    {
                        for (long i = 1; i <= count; i++)
                        {
                            this.SendMessage(mail, true, "实验二", "第" + i + "条", true, false);
                        }
                    }
                }

                #endregion
            }
            else if (this.rdoThree.Checked)
            {
                #region 实验三:批量邮件同步和异步发送 (平行类库Parallel(自动分区),每个分区一个MailHelper、SmtpClient实例,SendAsync())

                long count = long.Parse(this.cbbNumber.Text);
                if (count != 1)
                {
                    int  fenzu     = 0;
                    long sendCount = 0;

                    #region 由系统负荷自动分配最大并发度
                    // Environment.ProcessorCount; 并行度设置过大会导致资源争用问题,效率不高
                    // ParallelOptions parallelOptions = new ParallelOptions();
                    // parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount;
                    #endregion

                    ParallelOptions parallelOptions = new ParallelOptions();
                    // 用一半的线程,因为内部发邮件需要线程池线程
                    parallelOptions.MaxDegreeOfParallelism = (int)Math.Ceiling((double)Environment.ProcessorCount / 2d);

                    Parallel.For <ParallelInitObj>(1, count + 1
                                                   , parallelOptions, () =>
                    {
                        Interlocked.Increment(ref fenzu);
                        Debug.WriteLine("开始一个分组,当前分组数为:" + fenzu.ToString());
                        ParallelInitObj initObj = new ParallelInitObj()
                        {
                            mail     = new MailHelper(isAsync),
                            SumCount = 0,
                        };
                        return(initObj);
                    }
                                                   , (i, loop, initObj) =>
                    {
                        ParallelInitObj curInitObj = initObj;
                        MailHelper mail            = curInitObj.mail;

                        Interlocked.Increment(ref sendCount);
                        string shiyan = String.Format("({0})实验三", Thread.CurrentThread.ManagedThreadId);

                        if (isReuse)
                        {
                            if (isAsync)
                            {
                                this.SendMessageAsync(mail, false, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, true);
                                curInitObj.SumCount++;
                            }
                            else
                            {
                                this.SendMessage(mail, false, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, true);
                                curInitObj.SumCount++;
                            }
                        }
                        else
                        {
                            if (isAsync)
                            {
                                this.SendMessageAsync(mail, true, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, false);
                            }
                            else
                            {
                                this.SendMessage(mail, true, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, false);
                            }
                        }
                        return(curInitObj);
                    }
                                                   , (initObj) =>
                    {
                        ParallelInitObj curInitObj = initObj;
                        if (isReuse)
                        {
                            curInitObj.mail.SetBatchMailCount(curInitObj.SumCount);
                        }
                        Interlocked.Decrement(ref fenzu);
                        Debug.WriteLine("结束一个分组,当前分组数为:" + fenzu.ToString());
                    });
                }
                else
                {
                    MessageBox.Show("分区发邮件不能为一封");
                }

                #endregion
            }
            else if (this.rdoFour.Checked)
            {
                #region 实验四:批量邮件同步和异步发送 (平行类库Parallel(手动分区),每个分区一个MailHelper、SmtpClient实例)

                long count = long.Parse(this.cbbNumber.Text);

                if (count != 0)
                {
                    int  fenzu     = 0;
                    long sendCount = 0;

                    #region 由系统负荷自动分配最大并发度
                    // OrderablePartitioner<Tuple<long, long>> orderPartition = Partitioner.Create(1, count + 1, Environment.ProcessorCount);
                    // ParallelOptions parallelOptions = new ParallelOptions();
                    // parallelOptions.MaxDegreeOfParallelism = (int)Math.Ceiling((double)Environment.ProcessorCount);
                    #endregion

                    OrderablePartitioner <Tuple <long, long> > orderPartition = Partitioner.Create(1, count + 1, (count / (int)Math.Ceiling((double)Environment.ProcessorCount / 2d)));

                    ParallelOptions parallelOptions = new ParallelOptions();
                    parallelOptions.MaxDegreeOfParallelism = (int)Math.Ceiling((double)Environment.ProcessorCount / 2d);

                    Parallel.ForEach <Tuple <long, long>, ParallelInitObj>(orderPartition,
                                                                           parallelOptions, () =>
                    {
                        Interlocked.Increment(ref fenzu);
                        Debug.WriteLine("开始一个分组,当前分组数为:" + fenzu.ToString());
                        ParallelInitObj initObj = new ParallelInitObj()
                        {
                            mail     = new MailHelper(),
                            SumCount = 0,
                        };
                        return(initObj);
                    }
                                                                           , (source, loop, loopIndex, initObj) =>
                    {
                        ParallelInitObj curInitObj = initObj;
                        MailHelper mail            = curInitObj.mail;

                        string shiyan = String.Format("({0})实验四", Thread.CurrentThread.ManagedThreadId);

                        for (long i = source.Item1; i < source.Item2; i++)
                        {
                            Interlocked.Increment(ref sendCount);
                            if (isReuse)
                            {
                                if (isAsync)
                                {
                                    this.SendMessageAsync(mail, false, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, true);
                                    curInitObj.SumCount++;
                                }
                                else
                                {
                                    this.SendMessage(mail, false, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, true);
                                    curInitObj.SumCount++;
                                }
                            }
                            else
                            {
                                if (isAsync)
                                {
                                    this.SendMessageAsync(mail, true, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, false);
                                }
                                else
                                {
                                    this.SendMessage(mail, true, shiyan, "第" + Thread.VolatileRead(ref sendCount) + "条", true, false);
                                }
                            }
                        }
                        return(curInitObj);
                    }
                                                                           , (initObj) =>
                    {
                        ParallelInitObj curInitObj = initObj;
                        if (isReuse)
                        {
                            curInitObj.mail.SetBatchMailCount(curInitObj.SumCount);
                        }
                        Interlocked.Decrement(ref fenzu);
                        Debug.WriteLine("结束一个分组,当前分组数为:" + fenzu.ToString());
                    });
                }
                else
                {
                    MessageBox.Show("分区发邮件不能为一封");
                }

                #endregion
            }
        }