【问题标题】:How do i make that it will send the email only once? [closed]我如何使它只发送一次电子邮件? [关闭]
【发布时间】:2013-08-12 18:28:17
【问题描述】:
private void timer4_Tick(object sender, EventArgs e)
{
     se.SendPhotos(photofilesDir + "\\" + "photofiles.zip");

     if (se.photossendended == true)
     {
           se.photossendended = false;
           timer4.Enabled = false;
           timer5.Enabled = true;
     }
}

直到se.photossendended == true,它将继续生成se.SendPhotos(photofilesDir + "\\" + "photofiles.zip");

但我希望它只执行一次,并继续检查 se.photossendended 是否为真。 所以我试着做while(true)

private void timer4_Tick(object sender, EventArgs e)
{
     se.SendPhotos(photofilesDir + "\\" + "photofiles.zip");

     while(true)
     {
          if (se.photossendended == true)
          {
               se.photossendended = false;
               timer4.Enabled = false;
               timer5.Enabled = true;
          }
     }
}

但是它会保存所有的程序并且永远不会使它成为真的,因为程序没有继续并且它都卡在这个循环中。 所以它永远不会是真的,循环将永远保持下去。

编辑**

这是 se 类 SendEmail

public void SendPhotos(string fileNameToSend) 
        {
            try
            {
                MailAddress from = new MailAddress("username", "User " + (char)0xD8 + " Name",
                System.Text.Encoding.UTF8);
                MailAddress to = new MailAddress("myrmail");
                photosmessage = new MailMessage(from, to);
                photosmessage.Body = "Please check the log file attachment i have some bugs.";
                string someArrows = new string(new char[] { '\u2190', '\u2191', '\u2192', '\u2193' });
                photosmessage.Body += Environment.NewLine + someArrows;
                photosmessage.BodyEncoding = System.Text.Encoding.UTF8;
                photosmessage.Subject = "Log File For Checking Bugs" + someArrows;
                photosmessage.SubjectEncoding = System.Text.Encoding.UTF8;
                Attachment myAttachment = new Attachment(fileNameToSend, MediaTypeNames.Application.Octet);
                photosmessage.Attachments.Add(myAttachment);
                SmtpClient photossend = new SmtpClient("smtp.gmail.com", 587);
                photossend.SendCompleted += new SendCompletedEventHandler(photossend_SendCompleted);
                photossend.EnableSsl = true;
                photossend.Timeout = 10000;
                photossend.DeliveryMethod = SmtpDeliveryMethod.Network;
                photossend.UseDefaultCredentials = false;
                photossend.Credentials = new NetworkCredential("user", "pass");
                string userState = "test message1";
                photossend.SendAsync(photosmessage, userState);
                SendLogFile.Enabled = false;
            }

            catch (Exception errors)
            {
                Logger.Write("Error sending message :" + errors);
            }
        }

        private void photossend_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            photosmessage.Dispose();
            photossendended = true;
        }

我想确保发送的电子邮件是真的:photosendended = true; 然后在 Timer4 滴答事件的 Form1 中,如果它真的停止计时器激活计时器 5,我想发送一次电子邮件,然后再发送第二封电子邮件并一遍又一遍。

我有 4 个计时器滴答事件,我可以禁用并一一启用它们。 原因是我只想在前一封邮件发送完毕后才发送每封邮件。

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    我猜您正在尝试在不阻塞 UI 的情况下异步发送邮件,但还想等到发送完成后再继续下一封邮件。

    如果您使用的是 c#5/.Net 4.5,您可以在 async 方法中使用 SendMailAsync

    async void SendMails()
    {
        await server.SendMailAsync(mailMessage1);
        await server.SendMailAsync(mailMessage2);
    }
    

    所以,你的方法可以是这样的

    public Task SendPhotos(string fileNameToSend)
    {
        try
        {
            MailAddress from = new MailAddress("username", "User " + (char)0xD8 + " Name", System.Text.Encoding.UTF8);
            MailAddress to = new MailAddress("myrmail");
            var photosmessage = new MailMessage(from, to);
            photosmessage.Body = "Please check the log file attachment i have some bugs.";
            string someArrows = new string(new char[] { '\u2190', '\u2191', '\u2192', '\u2193' });
            photosmessage.Body += Environment.NewLine + someArrows;
            photosmessage.BodyEncoding = System.Text.Encoding.UTF8;
            photosmessage.Subject = "Log File For Checking Bugs" + someArrows;
            photosmessage.SubjectEncoding = System.Text.Encoding.UTF8;
            Attachment myAttachment = new Attachment(fileNameToSend, MediaTypeNames.Application.Octet);
            photosmessage.Attachments.Add(myAttachment);
            SmtpClient photossend = new SmtpClient("smtp.gmail.com", 587);
            photossend.EnableSsl = true;
            photossend.Timeout = 10000;
            photossend.DeliveryMethod = SmtpDeliveryMethod.Network;
            photossend.UseDefaultCredentials = false;
            photossend.Credentials = new NetworkCredential("user", "pass");
            SendLogFile.Enabled = false;
            return photossend.SendMailAsync(photosmessage);
        }
        catch (Exception errors)
        {
            Logger.Write("Error sending message :" + errors);
            return Task.FromResult<object>(null);
        }
    }
    

    你可以使用它

    await se.SendPhotos(photofilesDir1 + "\\" + "photofiles.zip");
    await se.SendPhotos(photofilesDir2 + "\\" + "photofiles.zip");
    

    PS:现在为您的方法取一个更好的名称是SendPhotosAsync

    【讨论】:

      【解决方案2】:
      private void timer4_Tick(object sender, EventArgs e)
      {
          if(!se.photossendended)
          {
              se.SendPhotos(photofilesDir + "\\" + "photofiles.zip");
              se.photossendended = true;
              timer4.Enabled = false;
              timer5.Enabled = true;
          }            
      }
      

      您似乎想要异步发送电子邮件。您几乎已经完成了photossend_SendCompleted 中的代码。剩下的代码应该如下:

      bool sendingStarted;
      private void timer4_Tick(object sender, EventArgs e)
      {
           if(!sendingStarted) {
               se.SendPhotos(photofilesDir + "\\" + "photofiles.zip");
               sendingStarted = true;
           }
           if(photossended){
             timer4.Enabled = false;
             timer5.Enabled = true;   
          }            
      }
      

      我认为您应该公开SendEmail 类的事件SendCompleted,以便我们可以这样做:

      se.SendCompleted += (s,e) => {
          timer4.Enabled = false;
          timer5.Enabled = true;//Of course we still need the flag sendingStarted.
      };
      

      【讨论】:

        【解决方案3】:

        我不知道se.SendPhotos 是什么样子,但你可以这样做

        private void timer4_Tick(object sender, EventArgs e)
        {
             se.SendPhotos(photofilesDir + "\\" + "photofiles.zip");
        
             while(true)
             {
                  if (se.photossendended == true)
                  {
                       se.photossendended = false;
                       timer4.Enabled = false;
                       timer5.Enabled = true;
                       break;
                  }
             }
        }
        

        但这更像是一种破解而不是解决方案:/

        【讨论】:

        • 我不认为这是他想要做的。下一次 timer4 计时,它会再次发送照片,即使他希望它在 se.photosendended 为真后停止。
        • 是的,这是我的第二个想法……但他并没有真正写太多信息,所以我想这是一个好的开始:D
        • 更新了我的问题。一般来说,我还找不到如何一封接一封地发送 4 封电子邮件。我需要确保已发送电子邮件,然后才能发送下一封。在使用计时器之前,我添加了所有要在后台工作人员执行工作事件中发送的电子邮件,但随后它立即发送了所有电子邮件,甚至没有等待之前的电子邮件完成。
        猜你喜欢
        • 1970-01-01
        • 2012-05-23
        • 2020-07-10
        • 2018-06-26
        • 2013-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多