gpt4 book ai didi

c# - 在 ASP.NET 中异步发送电子邮件的正确方法...(我做对了吗?)

转载 作者:IT王子 更新时间:2023-10-29 04:37:10 25 4
gpt4 key购买 nike

当用户在我的网站上注册时,我不明白为什么我需要让他“等待”smtp 通过以便他收到激活电子邮件。

我决定要异步启动这段代码,这是一次冒险。

假设我有一个方法,例如:

private void SendTheMail() { // Stuff }

虽然我的第一个......是线程。我这样做了:

Emailer mailer = new Emailer();
Thread emailThread = new Thread(() => mailer.SendTheMail());
emailThread.Start();

这行得通……直到我决定测试它的错误处理能力。我故意破坏了 web.config 中的 SMTP 服务器地址并进行了尝试。可怕的结果是 IIS 基本上因 w3wp.exe 上的未处理异常错误而被阻止(这是一个 Windows 错误!多么极端......)ELMAH(我的错误记录器)没有捕捉到它并且 IIS 被重新启动所以网站上的任何人都有他们的 session 被删除了。完全不能接受的结果!

我的下一个想法是对异步委托(delegate)进行一些研究。这似乎工作得更好,因为异常是在异步委托(delegate)中处理的(与上面的线程示例不同)。但是,我担心我是否做错了或者可能导致内存泄漏。

这是我正在做的:

Emailer mailer = new Emailer();
AsyncMethodCaller caller = new AsyncMethodCaller(mailer.SendMailInSeperateThread);
caller.BeginInvoke(message, email.EmailId, null, null);
// Never EndInvoke...

我这样做对吗?

最佳答案

我在这里赞成很多好的建议...例如确保记住使用 IDisposable(我完全不知道)。我还意识到在另一个线程中手动捕获错误是多么重要,因为没有上下文——我一直在研究一个理论,我应该让 ELMAH 处理所有事情。此外,进一步探索让我意识到我也忘记了在 mailmessage 上使用 IDisposable。

作为对 Richard 的回应,虽然我看到线程解决方案可以工作(如我的第一个示例中所建议的那样),但只要我捕捉到错误...如果 IIS 完全爆炸,仍然有一些可怕的事实没有发现错误。这告诉我 ASP.NET/IIS 从来没有让你这样做的意思......这就是为什么我倾向于继续使用 .BeginInvoke/delegates 因为当出现问题时它不会弄乱 IIS 并且似乎在 ASP.NET 中更受欢迎。

作为对 ASawyer 的回应,我对 SMTP 客户端中内置的 .SendAsync 感到非常惊讶。我使用该解决方案玩了一段时间,但它似乎对我不起作用。虽然我可以跳过执行 SendAsync 的代码客户端,但页面仍然“等待”直到 SendCompleted 事件完成。我的目标是在后台发送电子邮件时让用户和页面向前移动。我有一种感觉,我可能仍然做错了什么……所以如果有人遇到这个问题,他们可能想自己尝试一下。

除了 ELMAH.MVC 错误记录之外,这是我如何 100% 异步发送电子邮件的完整解决方案。我决定使用示例 2 的扩展版本:

public void SendThat(MailMessage message)
{
AsyncMethodCaller caller = new AsyncMethodCaller(SendMailInSeperateThread);
AsyncCallback callbackHandler = new AsyncCallback(AsyncCallback);
caller.BeginInvoke(message, callbackHandler, null);
}

private delegate void AsyncMethodCaller(MailMessage message);

private void SendMailInSeperateThread(MailMessage message)
{
try
{
SmtpClient client = new SmtpClient();
client.Timeout = 20000; // 20 second timeout... why more?
client.Send(message);
client.Dispose();
message.Dispose();

// If you have a flag checking to see if an email was sent, set it here
// Pass more parameters in the delegate if you need to...
}
catch (Exception e)
{
// This is very necessary to catch errors since we are in
// a different context & thread
Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
}
}

private void AsyncCallback(IAsyncResult ar)
{
try
{
AsyncResult result = (AsyncResult)ar;
AsyncMethodCaller caller = (AsyncMethodCaller)result.AsyncDelegate;
caller.EndInvoke(ar);
}
catch (Exception e)
{
Elmah.ErrorLog.GetDefault(null).Log(new Error(e));
Elmah.ErrorLog.GetDefault(null).Log(new Error(new Exception("Emailer - This hacky asynccallback thing is puking, serves you right.")));
}
}

关于c# - 在 ASP.NET 中异步发送电子邮件的正确方法...(我做对了吗?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8747483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com