0

在我的 C# windows 应用程序中,我构建了一个自动邮件系统来通知用户他们使用 SMTP 设置在应用程序中设置的关键事件......这个邮件系统工作正常。我已经使用 System.Net.Mail 命名空间来实现这一点......

我的问题是,每当邮件发送成功时,我需要在一个窗体上显示一个通知窗口(弹出窗口),显示收件人的姓名和他的电子邮件 ID。

为此,我正在使用辅助线程,但它无法正常工作,它使我的主应用程序无响应,直到它将邮件传递给所有用户。对于每封邮件已经给线程睡眠 5 秒,考虑有 10 封邮件,那么我将无法使用我的主应用程序 50 秒......所以任何帮助将不胜感激......

我已经完成了这样的 C# 编码:

    //My main Function
    public void SendMail(dataset ds)
    {
      for(inti=0;i<ds.Tables[0].Rows.Count;i++)
      {
       string resValue = genFunc.SMTPClienTSetting(ds, mail);
        if (resValue == "True")
        {
            Thread tPopUp = new Thread(new ThreadStart(this.ShowMessagePopUp));
            tPopUp.IsBackground = true;
            tPopUp.Start();
            lblPOpUpInfo = "Message sent successfully";
        }
        else
        {
            Thread tPopUp = new Thread(new ThreadStart(this.ShowMessagePopUp));
            tPopUp.IsBackground = true;
            tPopUp.Start();
            lblPOpUpInfo = "Message sending failed";
        }
       }
    }

    //Thread Function to open secondary form
    public void ShowMessagePopUp()
    {
        try
        {
            frmHomePopUp homePopUp = new frmHomePopUp();
            homePopUp.Show();
            homePopUp.lblInfo.Text = lblPOpUpInfo;
            Application.DoEvents();
            Thread.Sleep(5000);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

public string SMTPClienTSetting(DataSet ds, MailMessage MailstoSend)
        {
            try
            {
                SmtpClient objsmtp = new SmtpClient();
                NetworkCredential NetAccess = new NetworkCredential();

                NetAccess.UserName = ds.Tables[0].Rows[0][0].ToString();
                NetAccess.Password = ds.Tables[0].Rows[0][1].ToString();
                objsmtp.Credentials = NetAccess;
                objsmtp.Host = ds.Tables[0].Rows[0][2].ToString();
                objsmtp.Port = Convert.ToInt16(ds.Tables[0].Rows[0][3].ToString());

                objsmtp.Send(MailstoSend);

                System.Threading.Thread.Sleep(500);

                return "True";
            }
            catch (NullReferenceException nr)
            {
                return nr.Message;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

我可以使用线程显示我的表单,但主应用程序在完成发送邮件之前没有响应......

4

3 回答 3

2

您可以TPL用于异步邮件发送和ContinueWith与 UI 线程的交互。类似的东西

for (int i = 0; i < 10; i++)
{
    var asyncTask = Task.Factory.StartNew(() => SendMail(i)).ContinueWith((result) =>
    {
        // UI interaction logic
    });
}
private bool SendMail(string data)
{
    // send logic
    // you can handle result from this function in ContinueWith delegate function
}
于 2013-01-02T12:34:51.813 回答
0

您的阻塞代码实际上包含在SMTPClientTSetting方法中,在您的情况下,该方法在主线程(UI 线程)上执行。为了避免 UI 阻塞,您应该在不同的线程上执行此方法(您可以使用 Vadim 建议的方法)。

于 2013-01-02T13:34:54.230 回答
0

我认为这里不需要新线程。此外,请避免使用 DoEvents,请参阅此处或自行搜索。您是否考虑过制作一个小型列表框作为某种控制台/日志并在那里显示成功或失败消息?每个用户都讨厌总是到处乱扔消息框的应用程序。

于 2013-01-02T12:29:57.260 回答