2

我正在使用 SmtpClient 发送电子邮件。我在以下位置创建了一些功能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();
}

在表单中,我在关闭表单之前调用该函数,但是在等待来自 SendCompletedCallback 的响应时,将执行 this.Close():

Mail mail = new Mail();
mail.SentEmail();
this.Close();

在收到 SendCompletedCallback 的响应之前,如何阻止表单关闭?

4

2 回答 2

1

如果您的用户决定强行关闭其计算机,您几乎无能为力。(关闭,任务终止或其他)。
但是,您可以连接Form_Closing事件并将e.Cancel内部的属性更改CloseEventArgs为 true,可能会使用消息框通知您的用户挂起的操作。

首先将一个全局变量添加到您的 Main 表单(或您所称的任何名称)中,作为状态标志:

private bool eMailSentPendingComplete = false;

然后在您的SentMail方法中,在 client.SentAsync 之后添加这一行:

eMailSentPendingComplete = true;

SendCompletedCallback
在 FormClosing 事件 中和主窗体中将其重置为 false :

    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);
        }
    }

同样在 FormClosing 事件中,您可以查看属性 e.CloseReason 以进行进一步优化。

于 2012-06-07T08:32:03.643 回答
0

选项1

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 
    }
}

从调用表单订阅此事件:

Mail m = new Mail();
m.OnMailSendComplete += new Mail.MailSendComplete(m_OnMailSendComplete);
m.SentEmail();

当您收到完整事件时,您可以关闭表单 void m_OnMailSendComplete() { this.Close(); }

选项 2

当您创建 Mail 对象时,您可以将当前表单引用传递给它

Mail mail = new Mail(this);

然后在 SendCompletedCallback 结束时,您可以关闭表单

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();
    }
}
于 2012-06-07T08:33:43.033 回答