コード例 #1
0
        // 开始发件
        public Task Run(Stack <SendItem> sendItems)
        {
            // 创建线程
            Task task = Task.Run(async() =>
            {
                while (sendItems.Count > 0)
                {
                    // 开始并行发送
                    //确定smtp服务器地址 实例化一个Smtp客户端
                    SmtpClient smtpclient = new SmtpClient();
                    smtpclient.Host       = _sendBox.smtp;
                    //smtpClient.Port = "";//qq邮箱可以不用端口
                    //邮件发送方式  通过网络发送到smtp服务器
                    smtpclient.DeliveryMethod = SmtpDeliveryMethod.Network;
                    //如果服务器支持安全连接,则将安全连接设为true
                    smtpclient.EnableSsl = true;

                    // 获取发件箱
                    var sendItem    = sendItems.Pop();
                    var mailMessage = await GenerateMailMessage(sendItem);
                    try
                    {
                        //是否使用默认凭据,若为false,则使用自定义的证书,就是下面的networkCredential实例对象
                        smtpclient.UseDefaultCredentials = false;
                        //指定邮箱账号和密码,需要注意的是,这个密码是你在QQ邮箱设置里开启服务的时候给你的那个授权码
                        NetworkCredential networkCredential = new NetworkCredential(_sendBox.email, _sendBox.password);
                        smtpclient.Credentials = networkCredential;

                        //发送邮件
                        smtpclient.Send(mailMessage);

                        // 发送成功后,更新数据,更新到数据库
                        sendItem.senderEmail = _sendBox.email;
                        sendItem.senderName  = _sendBox.userName;
                        sendItem.isSent      = true;
                        sendItem.sendMessage = "邮件送达";
                        sendItem.sendDate    = DateTime.Now;
                        _liteDb.Upsert(sendItem);

                        // 更新到当前进度中
                        SendCompleted?.Invoke(new SendResult()
                        {
                            SendBox  = _sendBox,
                            SendItem = sendItem,
                            IsSent   = true,
                        });

                        // 保存成功的发件量
                        if (!_sendBox.IncreaseSentCount(_liteDb, _setting))
                        {
                            // 直接退出
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        // 超过最大尝试次数就退出
                        if (sendItem.tryCount > 5)
                        {
                            // 此时也要更新进度
                            SendCompleted?.Invoke(new SendResult()
                            {
                                SendBox  = _sendBox,
                                SendItem = sendItem,
                                IsSent   = false
                            });
                        }
                        else if (_setting.isAutoResend) // 重新发送时,才重新推入栈中
                        {
                            // 更新状态
                            sendItem.tryCount++;
                            sendItem.isSent = false;

                            // 重新推入栈中
                            sendItems.Push(sendItem);
                        }

                        // 添加失败原因
                        if (ex.InnerException == null)
                        {
                            sendItem.sendMessage = ex.Message;
                        }
                        else
                        {
                            sendItem.sendMessage = ex.InnerException.Message;
                        }
                        _liteDb.Upsert(sendItem);

                        // 标记当前邮件失败次数
                        // 要等数据处理保存后,再更新
                        IncreaseFailure();
                    }
                    finally
                    {
                        // 每次发送完成,要等待一会儿再发送
                        double sleep = new Random().NextDouble() * 3 + 2;
                        if (_setting != null)
                        {
                            sleep = _setting.sendInterval_min + new Random().NextDouble() * (_setting.sendInterval_max - _setting.sendInterval_min);
                        }

                        // 线程暂停
                        Thread.Sleep((int)(sleep * 1000));
                    }
                }
            }, _cancellationTokenSource.Token);

            return(task);
        }