在c# Windows应用程序中使用二级线程打开新的弹出窗口不工作
本文关键字:线程 工作 窗口 二级 应用程序 Windows | 更新日期: 2023-09-27 17:50:36
在我的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;
}
}
我可以使用using线程显示我的表单,但是主应用程序没有响应,直到它完成发送邮件....
您可以使用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
}
我不认为这里需要一个新的线程。此外,避免使用DoEvents,请参阅此处或自己搜索。你是否考虑过制作一个小的Listbox作为某种控制台/日志,并在那里显示成功或失败的消息?每个用户都讨厌那些总是乱扔消息框的应用程序。
您的阻塞代码实际上包含在SMTPClienTSetting方法中,在您的情况下,该方法在主线程(UI线程)上执行。为了避免UI阻塞,你应该在不同的线程上执行这个方法(你可以使用Vadim建议的方法)。