[英]How can I wait for a thread to finish running?Thread.join is making my main thread non responsive?
我正在研究使用Windows应用程序将邮件发送给多个用户的项目,但是发生的是,当我使用Thread.Join()方法时,它使我的主UI无响应……我想要的是....我想在单独的线程上运行SMTPClienTSetting()方法,并希望我的主UI保持对其他工作的响应。.我要在后台运行此发送邮件的邮件...请仅使用线程概念来建议我。 ....
public void SendMail(dataset ds)
{
for(inti=0<ds.Tables[0].Rows.Count<i++)
{
Thread tMail = new Thread(() => {
resValue = SMTPClienTSetting(ds, mail);
});
tMail.IsBackground = true;
tMail.Start();
tMail.Join();
if (resValue == "True")
{
Thread tPopUp = new Thread(new ThreadStart(this.ShowMessagePopUp));
tPopUp.IsBackground = true;
this.BeginInvoke((MethodInvoker)delegate{
});
tPopUp.Start();
lblPOpUpInfo = "Message sent successfully to \nAsset Owner : " + AssetOwner + "\n" + "Email : " + RecipientID;
}
else
{
Thread tPopUp = new Thread(new ThreadStart(this.ShowMessagePopUp));
tPopUp.IsBackground = true;
this.BeginInvoke((MethodInvoker)delegate{
});
tPopUp.Start();
lblPOpUpInfo = "Message sending failed to \nAsset Owner :" + AssetOwner + "\n" + "Email : " + RecipientID + "!!!\nPlease check your SMTP details and\nInternet Connection..!!!";
}
}
}
#region Function for setting SMTP Client
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 = base64Decode(ds.Tables[0].Rows[0][1].ToString());
NetAccess.Password = genFunc.base64Decode(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;
}
}
#endregion
}
#region Function to show Pop Up window using separate thread
public void ShowMessagePopUp()
{
try
{
frmHomePopUp homePopUp = new frmHomePopUp();
mailTimer.Elapsed += delegate { mailTimer.Stop(); homePopUp.Close(); };
//mailTimer.Elapsed += this.TimeEvent;
mailTimer.Interval=5000;
mailTimer.Enabled = true;
homePopUp.lblInfo.Text = lblPOpUpInfo;
homePopUp.Refresh();
mailTimer.Start();
homePopUp.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#endregion
public void mailTimer_Elapsed(object source, EventArgs e)
{
//frmHome home;
mailTimer.Stop();
}
基本上:不要使用Thread.Join
; 这是什么做的是块。
一种适当的方法是在worker方法的末尾进行任何UI工作:
Thread tMail = new Thread(() => {
resValue = SMTPClienTSetting(ds, mail);
if (resValue == "True") {
// blah blah blah
}
// now: if you need to update any UI state:
this.BeginInvoke((MethodInvoker)delegate {
someControl.Text = lblPOpUpInfo; // for example
});
});
tMail.IsBackground = true;
tMail.Start();
对Invoke
/ BeginInvoke
Invoke
切换回UI线程,本质上用作回调。
请注意,您可能还想在这里使用ThreadPool
而不是Thread
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.