I’m working on project which sends mails to multiple users using windows application,But what is happening is,when I use Thread.Join() Method it is making my Main UI non-responsive……
What I want is…. I want to run SMTPClienTSetting() method on seperate thread and want my Main UI to remain responsive for other work..I wnat to run this mail sending acvtivity at the background…Please suggest me using threading concept only…..
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();
}
Basically: don’t use
Thread.Join; what that does is block.An appropriate approach would be to do any UI work at the end of the worker method:
The call to
Invoke/BeginInvokeswitches back to the UI thread, essentially working as a callback.Note that you might also want to use
ThreadPoolrather than aThreadhere.