Reputation: 8499
I am using SmtpClient to sent out email. I create some function in Mail class
:
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// Get the unique identifier for this asynchronous operation.
String token = (string)e.UserState;
if (e.Cancelled)
{
MailStatus = Status.CANCEL;
MailStatusMessage = token + " Send canceled.";
}
else if (e.Error != null)
{
MailStatus = Status.ERROR;
MailStatusMessage = token + " " + e.Error.ToString();
}
else
{
MailStatus = Status.SENT;
MailStatusMessage = "Mail sent.";
}
mailSent = true;
}
public void SentEmail()
{
client = new SmtpClient(Host, Port);
client.Credentials = new NetworkCredential(UserName, Password);
MailAddress from = new MailAddress(MerchantEmail, MerchantName);
MailAddress to = new MailAddress(CustomerEmail);
MailMessage message = new MailMessage(from, to);
message.Body = EmailSubjectTemplate();
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Subject = EmailSubjectTemplate();
message.SubjectEncoding = System.Text.Encoding.UTF8;
client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
client.SendAsync(message, "Sending message.");
message.Dispose();
}
In a form I call the function, before closing the form, but when waiting for the response from the SendCompletedCallback, the this.Close() will be executed:
Mail mail = new Mail();
mail.SentEmail();
this.Close();
How can I stop the form from closing before I get a response from SendCompletedCallback?
Upvotes: 2
Views: 1199
Reputation: 63095
public class Mail
{
public delegate void MailSendComplete();
public event MailSendComplete OnMailSendComplete;
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// your code
// finally call the complete event
OnMailSendComplete();
}
public void SentEmail()
{
// your code
}
}
subscribe to this event from calling form as:
Mail m = new Mail();
m.OnMailSendComplete += new Mail.MailSendComplete(m_OnMailSendComplete);
m.SentEmail();
When you receive the complete event you can close the form void m_OnMailSendComplete() { this.Close(); }
when you create Mail object you can pass current form reference to it
Mail mail = new Mail(this);
then at the end of SendCompletedCallback you can close the form
public class Mail
{
public Form form { get; set; }
public Mail(Form f)
{
form = f;
}
private void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
// your code
// finally close the form
form.Close();
}
}
Upvotes: 0
Reputation: 216313
There is little that you can do if your user decides to forcibly close its computer. (switch off, task kill or whatever).
However, you can wire the Form_Closing
event and change the e.Cancel
property inside the CloseEventArgs
to true, perhaps with a messagebox informing your user of the pending operation.
First add to your Main form (or whatever you call it) a global var acting as a status flag:
private bool eMailSentPendingComplete = false;
then in your SentMail
method add this line just after the client.SentAsync:
eMailSentPendingComplete = true;
reset it to false in the SendCompletedCallback
and in your Main Form wire the FormClosing event:
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if(eMailSentPendingComplete == true)
{
DialogResult dr = MessageBox.Show("Pending email, do you wish to close?", MEssageBoxButtons.YesNo);
e.Cancel = (dr == DialogResult.Yes ? true : false);
}
}
also in the FormClosing event you can take a look to the property e.CloseReason for further optimizations.
Upvotes: 1