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

ユーザーが強制的にコンピュータを閉じることにした場合、できることはほとんどありません。(スイッチオフ、タスクキルなど)。ただし、保留中の操作をユーザーに通知するメッセージ ボックスを使用して、イベントを
配線し、内部のプロパティを true に変更することができます。Form_Closinge.CancelCloseEventArgs

最初にメイン フォーム (またはそれを何と呼ぶか​​) に、ステータス フラグとして機能するグローバル var を追加します。

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 に答える