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 } }