0

ユーザーがボタンを押したときに電子メールを送信する、私が書いたこのメソッドがあります。今私が直面している問題は、ユーザーがボタンを押すたびに、フォームが数秒間フリーズしてからメールを送信することです。メソッドは機能していますが、フォームがフリーズする理由がわかりません。

string emailAddress = tbEmailAddress.Text + cbEmailAddress.Text;
string emailPassword = tbEmailPassword.Text;
string emailRecipient = tbEmailRecipient.Text;
string emailSubject = tbEmailSubject.Text;
string emailBody = rtbEmailBody.Text;
string smtpHost;
string smtpPort;

MailMessage email = new MailMessage(emailAddress, emailRecipient);

email.Subject = emailSubject;
email.Body = emailBody;

SmtpClient smtp = new SmtpClient("smtp.live.com", 587);
smtp.EnableSsl = true;
smtp.Credentials = new System.Net.NetworkCredential(emailAddress, emailPassword);

smtp.Send(email);
smtp.Dispose();

私が直面しているこの問題を回避する方法はありますか?

前もって感謝します。

4

5 に答える 5

4

制御を戻してメールを送信する前にメソッドを終了する必要があるため、フォームがフリーズします。メソッドを非同期で実行できます。

.NET Framework 4.5 と C# 5 を使用している場合は、async-awaitを使用して目的を達成できます。それ以外の場合は、メール送信を非同期で実行するParallel.Invoke(() => { SendMail()}),か、別のスレッドを起動して同じことを行うことができます。

また、C# で System.Net.Mail.MailMessage を非同期に送信すると、関連記事: C# でメールを非同期に送信しますか? も参照してください。

于 2013-10-02T10:21:08.443 に答える
1

SmtpClient.SendMailAsync(.NET 4.5) または以下を使用する必要がありますSendAsync

async Task SendMail()
{
    var email = CreateMailMessage();

    using (var smtp = new SmtpClient("smtp.live.com", 587) { 
          EnableSsl = true,
          Credentials = new NetworkCredential(emailAddress, emailPassword)
        })
    {
        await smtp.SendMailAsync(email);
    }
}
于 2013-10-02T10:32:48.780 に答える
1

別のスレッドでメソッドを呼び出すことができます。スレッドまたはタスクを使用してみてください。UI スレッドがタスク スレッドによってブロックされているためフリーズしているため、スレッドを分離して UI の応答を継続させることができます。

System.Threading.Thread execute = new System.Threading.Thread(delegate() 
{ /* execute method here here */ });
于 2013-10-02T10:25:39.713 に答える
1

ちょうど別の解決策..私はずっと良いと思います。タスクは、スレッド管理を気にすることなく、このようなことを管理できるように特別に設計されています。また、スレッドの実行がいつ終了したかを監視することもできます。

コードを独自のメソッドにラップすると、次のようなことができます。

var sendEmailTask = Task.Run(() => yourSendEmailMethod())
                            .ContinueWith(t => MessageBox.Show("Email sent"));

既に述べたように、問題はアプリケーションが単一のスレッドで実行されるためです。メールが送信されている間、そのスレッドはブロックされます。新しいスレッドを作成すると (私の例ではそれを行うために Task を使用します)、電子メールはそのスレッドを使用して送信され、アプリケーション UI は独自のスレッドで引き続き機能します。

于 2013-10-02T10:26:58.220 に答える
0

プログラムの既定のスレッドを使用して電子メールを送信しているため、フォームがフリーズします。Windows イベントを処理するためにアプリ内のすべてのウィンドウで使用される同じスレッド。電子メールを送信している間、Windows は Windows メッセージを処理できません。メール送信をバックグラウンド スレッドに配置すると、アプリがブロックされなくなります。

于 2013-10-02T10:21:31.220 に答える