zoukankan      html  css  js  c++  java
  • WPF邮件群发工具开发 之 实现要点说明(完结篇)附工具下载

           紧接着上一篇文章“WPF邮件群发工具开发 之 进度条(属性改变通知机制)的实现”,这篇博文想把在工具开发中的实现要点跟大家交流、分享下,首先要说的是这个工具算是个Demo,实现的方法和功能都比较简单,还有不少细节需要完善...

      本文目录

         如何随机生成真实存在的QQ邮箱帐号?

      经过测试,通过C#代码发送邮件(调用SmtpClient类的Send方法,此方法无返回值,只会在发送邮箱账户错误或邮箱账户设置有问题,更多的是你用一个发送邮箱账户做群发,因为每种邮箱都有其这方面的限制,在连续很短时间内,只允许接收同一个邮箱发送的限量的邮件,如:QQ的限制大概50个左右),即使给一个根本不存在的邮箱里发送邮件,不会抛出异常,也更无法知道是否已发送成功,只能默认为发送成功,这样一说,似乎随机生成真实存在的QQ邮箱帐号是无法实现的事。——其实不然,可以用一个或几个qq邮箱账户检测生成的QQ邮箱是否真实存在! 代码实现如下:

      

     1         /// <summary>
     2         /// 生成邮箱的事件处理
     3         /// </summary>
     4         /// <param name="sender"></param>
     5         /// <param name="e"></param>
     6         void btnGenerate_Email_Click(object sender, RoutedEventArgs e)
     7         {
     8             #region 判断
     9             string str = this.txtGenerateEmailCount.Text.Trim();
    10             if (string.IsNullOrEmpty(str))
    11             {
    12                 MessageBox.Show("请输入要生成的邮箱个数!");
    13                 return;
    14             }
    15             int generate_Email_Count = 0;
    16             int.TryParse(str, out generate_Email_Count);
    17             if (generate_Email_Count <= 0)
    18             {
    19                 MessageBox.Show("邮箱个数必须为大于0!");
    20                 return;
    21             }
    22             EmailAccount emailAccount = this._emailAccountList.Find(E => E.Smtp == "smtp.qq.com");
    23             if (emailAccount == null)
    24             {
    25                 MessageBox.Show("qq邮箱账户不存在!");
    26                 return;
    27             }
    28             #endregion
    29             this._sendEmailsPropertyChanged.PropertyData += this.GetInfoTip("生成QQ邮箱");
    30             EmailInfoEntity emailInfoEntity = new EmailInfoEntity()
    31             {
    32                 Title = this.txtEmailTitle.Text,
    33                 Body = this.txtEmailContent.Text,
    34                 DisplayName = this.txtDisplayName.Text.Trim(),
    35                 Attachment = _accessoriesFilePath,
    36                 Host = emailAccount.Smtp,
    37                 From = emailAccount.Email,
    38                 Pwd = emailAccount.Pwd
    39             };
    40             #region 线程处理
    41             this.StartSingleThreadWork(() =>
    42             {
    43                 int i = 0, num;
    44                 string email = string.Empty;
    45                 System.Random random = new Random();
    46                 bool isSuc;
    47                 while (i < generate_Email_Count)
    48                 {
    49                     num = random.Next(123456, 987654321);
    50                     email = string.Format("{0}@qq.com", num);
    51                     if (this._emailList.Contains(email))
    52                         continue;
    53                     emailInfoEntity.To = email;
    54                     isSuc = EmailHelper.SendEmail(emailInfoEntity);
    55                     Thread.Sleep(1000);
    56                     if (!isSuc)
    57                     {
    58                         _sendResult.SendFailEmails += string.Format("【{0}】:发送失败!{1}", email, Environment.NewLine);
    59                         continue;
    60                     }
    61                     this._emailList.Add(email);
    62                     this._sendEmailsPropertyChanged.PropertyData += email + Environment.NewLine;
    63                     i++;
    64                     Console.WriteLine(email);
    65                 }
    66                 MessageBox.Show("Generate Over");
    67             });
    68             #endregion
    69         }

         单线程的使用及注意

      

     1         /// <summary>
     2         /// 开始一个单线程工作
     3         /// </summary>
     4         /// <param name="threadStartHandle"></param>
     5         private void StartSingleThreadWork(ThreadStart threadStartHandle)
     6         {
     7             _thread = new Thread(() =>
     8             {
     9                 //禁用发送按钮
    10                 _sendResult.SendControlIsEnabled = false;
    11                 threadStartHandle();
    12                 //启用发送按钮
    13                 _sendResult.SendControlIsEnabled = true;
    14                 _thread.Abort();
    15                 _thread = null;
    16                 Console.WriteLine(threadStartHandle.Method.Name);//---此行代码不会执行,因为它位于 线程终止Abort方法之后,即Abort方法通知当前线程的使命已完成,其它的后续工作它将不会再执行!
    17             });
    18             _thread.Start();
    19         }

        除了上面代码中的注释说明,还有一点需要重点指出的是:.Net的公用语言运行时(CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。所以,当应用程序的窗体关闭时,你希望结束所有的线程,你可以把线程设置为后台线程,或在窗体关闭事件中检查是否存在的执行中的线程并对其销毁!

         群发工具开发综述

        为了提高邮件发送的命中率,基于上面所提到的问题,应该采用多个邮箱账户轮发

      核心代码如下:

      1 void btnSend_Click(object sender, RoutedEventArgs e)
      2         {
      3             #region 判断
      4             if (this._emailList == null || this._emailList.Count == 0)
      5             {
      6                 MessageBox.Show("当前要发送的邮箱为空!");
      7                 return;
      8             }
      9             string eamilTitle = this.txtEmailTitle.Text.Trim();
     10             if (string.IsNullOrEmpty(eamilTitle))
     11             {
     12                 MessageBox.Show("请输入email标题!");
     13                 return;
     14             }
     15             string emailContent = this.txtEmailContent.Text.Trim();
     16             if (string.IsNullOrEmpty(emailContent))
     17             {
     18                 MessageBox.Show("请输入email内容!");
     19                 return;
     20             }
     21             if (!string.IsNullOrEmpty(_accessoriesFilePath))
     22             {
     23                 if (!System.IO.File.Exists(_accessoriesFilePath))
     24                 {
     25                     MessageBox.Show("请确认所选附件是否存在!");
     26                     return;
     27                 }
     28             }
     29             #endregion
     30             string displayName = this.txtDisplayName.Text.Trim();
     31             int count = this._emailList.Count;
     32             this.progressBar.Maximum = count;
     33             #region 发送处理
     34             this.StartSingleThreadWork(() =>
     35             {
     36                 Console.WriteLine("The send count is :" + count);
     37                 bool isSuc;
     38                 int failCount = 0, i = 1;
     39                 string failTip = string.Empty;
     40                 foreach (string email in this._emailList)
     41                 {
     42                     _sendResult.CurrentSendNum = i;
     43                     _sendResult.ProgressBarNumShow = i + "/" + count;
     44                     _sendCount = 0;
     45                     _sendAccountLastIndex = -1;
     46                     isSuc = SendEmail(new EmailInfoEntity()
     47                     {
     48                         DisplayName = displayName,
     49                         Body = emailContent,
     50                         Title = eamilTitle,
     51                         Attachment = _accessoriesFilePath,
     52                         To = email
     53                     });
     54                     i++;
     55                     if (!isSuc)
     56                     {
     57                         failTip = string.Format("【{0}】:发送失败!{1}", email, Environment.NewLine);
     58                         _sendResult.SendResultMes += failTip;
     59                         _sendResult.SendFailEmails += failTip;
     60                         failCount++;
     61                     }
     62                     System.Threading.Thread.Sleep(1000);
     63                 }
     64                 string tipStr = ("failCount is :" + failCount);
     65                 _sendResult.SendResultMes += tipStr;
     66                 MessageBox.Show(tipStr);
     67             });
     68             #endregion
     69         }
     70 
     71 private bool SendEmail(EmailInfoEntity emailInfoEntity)
     72         {
     73             if (emailInfoEntity == null)
     74                 throw new ArgumentNullException("emailInfoEntity is Null");
     75             int sendAccountIndex = GetSendAccountIndex();
     76             EmailAccount emailAccount = _emailAccountList[sendAccountIndex];
     77             emailInfoEntity.Host = emailAccount.Smtp;
     78             emailInfoEntity.From = emailAccount.Email;
     79             emailInfoEntity.Pwd = emailAccount.Pwd;
     80             bool isSuc = EmailHelper.SendEmail(emailInfoEntity);
     81             _sendAccountLastIndex = sendAccountIndex;
     82             _sendResult.SendResultMes += string.Format("★From:{0}★To:{1}★---isSuc:{2}!{3}", emailInfoEntity.From, emailInfoEntity.To, isSuc, Environment.NewLine);
     83             _sendCount++;
     84             if (!isSuc)
     85             {
     86                 //如果发送失败且已发送次数_sendCount小于_emailAccountListCount,则再次发送
     87                 if (_sendCount < _emailAccountListCount)
     88                 {
     89                     //当前线程挂起1s,再次发送
     90                     System.Threading.Thread.Sleep(1000);
     91                     return SendEmail(emailInfoEntity);
     92                 }
     93             }
     94             return isSuc;
     95         }
     96 
     97         /// <summary>
     98         /// 获得当前发送邮件的邮箱账户的index
     99         /// </summary>
    100         /// <returns></returns>
    101         private int GetSendAccountIndex()
    102         {
    103             if (_emailAccountListCount > 1)
    104             {
    105                 int sendAccountIndex = new Random().Next(_emailAccountListCount);
    106                 if (_sendAccountLastIndex >= 0 && sendAccountIndex == _sendAccountLastIndex)
    107                     return GetSendAccountIndex();
    108                 return sendAccountIndex;
    109             }
    110             return 0;
    111         }

      工具运行效果图如下:

        

      好了,本文到此结束,希望有这么经验或更好的建议的朋友,能够多多交流!

      邮件群发工具.rar

  • 相关阅读:
    mysql常用基本命令
    mysql8.0.13下载与安装图文教程
    k8s ingress 增加跨域配置
    Jenkins 备份恢复插件 thinBackup 使用
    k8s HA master 节点宕机修复
    nginx 跨域问题解决
    mongodb 3.4.24 主从复制
    k8s 线上安装 jenkins并结合 jenkinsfile 实现 helm 自动化部署
    k8s helm 运用与自建helm仓库chartmuseum
    centos6 源码安装 unzip
  • 原文地址:https://www.cnblogs.com/know/p/2944307.html
Copyright © 2011-2022 走看看