- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试根据 VS2013 项目模板中的示例 AccountController 为 ASP.NET MVC5 网站设置电子邮件确认。我已经使用 SmtpClient
实现了 IIdentityMessageService
,尽量保持简单:
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
using(var client = new SmtpClient())
{
var mailMessage = new MailMessage("some.guy@company.com", message.Destination, message.Subject, message.Body);
await client.SendMailAsync(mailMessage);
}
}
}
调用它的 Controller 代码直接来自模板(提取到一个单独的操作中,因为我想排除其他可能的原因):
public async Task<ActionResult> TestAsyncEmail()
{
Guid userId = User.Identity.GetUserId();
string code = await UserManager.GenerateEmailConfirmationTokenAsync(userId);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = userId, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(userId, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
return View();
}
但是,当邮件发送失败时,我会出现奇怪的行为,但仅在一个特定的实例中,当主机以某种方式无法访问时。示例配置:
<system.net>
<mailSettings>
<smtp deliveryMethod="Network">
<network host="unreachablehost" defaultCredentials="true" port="25" />
</smtp>
</mailSettings>
</system.net>
在那种情况下,请求会出现死锁,永远不会向客户端返回任何内容。如果由于任何其他原因(例如主机主动拒绝连接)邮件发送失败,异常会正常处理,我会收到 YSOD。
查看 Windows 事件日志,似乎在同一时间范围内抛出 InvalidOperationException
,并显示消息“异步模块或处理程序已完成,而异步操作仍在挂起。”;如果我尝试在 Controller 中捕获 SmtpException
并在 catch block 中返回 ViewResult
,我会在 YSOD 中收到相同的消息。所以我认为 await
-ed 操作在任何一种情况下都无法完成。
据我所知,我正在遵循 SO 上其他帖子(例如 HttpClient.GetAsync(...) never returns when using await/async)中概述的所有 async/await 最佳实践,主要是“一直使用 async/await”。我也尝试过使用 ConfigureAwait(false)
,但没有任何变化。由于代码只有在抛出特定异常时才会死锁,所以我认为一般模式在大多数情况下都是正确的,但内部发生的某些事情使其在这种情况下不正确;但由于我对并发编程还很陌生,所以我觉得我可能是错的。
我做错了什么吗?我始终可以在 SendAsync 方法中使用同步调用(即 SmtpClient.Send()
),但感觉应该按原样工作。
最佳答案
试试这个实现,只需使用 client.SendMailExAsync
而不是 client.SendMailAsync
。让我们知道它是否有任何不同:
public static class SendMailEx
{
public static Task SendMailExAsync(
this System.Net.Mail.SmtpClient @this,
System.Net.Mail.MailMessage message,
CancellationToken token = default(CancellationToken))
{
// use Task.Run to negate SynchronizationContext
return Task.Run(() => SendMailExImplAsync(@this, message, token));
}
private static async Task SendMailExImplAsync(
System.Net.Mail.SmtpClient client,
System.Net.Mail.MailMessage message,
CancellationToken token)
{
token.ThrowIfCancellationRequested();
var tcs = new TaskCompletionSource<bool>();
System.Net.Mail.SendCompletedEventHandler handler = null;
Action unsubscribe = () => client.SendCompleted -= handler;
handler = async (s, e) =>
{
unsubscribe();
// a hack to complete the handler asynchronously
await Task.Yield();
if (e.UserState != tcs)
tcs.TrySetException(new InvalidOperationException("Unexpected UserState"));
else if (e.Cancelled)
tcs.TrySetCanceled();
else if (e.Error != null)
tcs.TrySetException(e.Error);
else
tcs.TrySetResult(true);
};
client.SendCompleted += handler;
try
{
client.SendAsync(message, tcs);
using (token.Register(() => client.SendAsyncCancel(), useSynchronizationContext: false))
{
await tcs.Task;
}
}
finally
{
unsubscribe();
}
}
}
关于c# - SmtpClient.SendMailAsync 在抛出特定异常时导致死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28333396/
我正在尝试从本地主机发送邮件.. 在执行此操作时,我有来自不同站点的方法来发送邮件..但是在执行此操作时,我对 smtpClient.send() 感到困惑和smtpClient.SendAsync(
我正在从事一个项目(不幸的是)需要允许的最大框架是 .NET 4。 在这个项目中,我尝试使用 SendAsync() 异步发送电子邮件,但由于某种原因,它发送失败(或者更确切地说,它只是不发送)。简单
考虑到 SmtpClient 有一个我没有使用的 SendAsync 方法,因此假设 StmpClient.Send 是同步的是否安全?我用它来发送带有临时文件附件的电子邮件,想知道我是否可以在之后立
我在多台(不是说:所有)Windows 8.x 机器上面临以下问题: 运行这段代码: var message = new MailMessage(); message.From = new MailA
如标题所述,将“SmtpClient::EnableSsl”设置为 true 的“System::Net::Mail::SmtpClient”需要哪些端口? documentation on the
如果我已将一些电子邮件排队等待通过 System.Net.Mail.SMTPClent 发送,我在哪里可以找到这封邮件?对于 Windows SMTP 客户端,它位于 C:\inetpub\mailr
.NET SmtpClient 对象中的超时默认值是多少?它是什么时间单位(秒、毫秒等)? 最佳答案 默认值为 100,000(100 秒)。 http://msdn.microsoft.com/en
我尝试使用 SmtpClient.Send() 从 c# 发送电子邮件,但它总是进入垃圾箱。如果我从 Outlook 发送它,它工作正常。无论如何要解决这个问题?有人告诉我修改电子邮件标题,但我不知道
我正在尝试使用 C# 创建一个小型应用程序来发送电子邮件,但即使使用端口 587 (GMail) TLS 或 465 (GMail SSL) 我也无法让它工作。我不确定是什么导致了我的问题,我应该编辑
当我使用 SmtpClient 发送电子邮件时,我发现了一个奇怪的行为: 送货时间太长。 已送达两次。 SmtpClient client = new SmtpClient(); client.Hos
我正在使用以下代码发送电子邮件: using (var mailMessage = new MailMessage("from@example.com", "to@example.com")) {
我遇到了一个让我抓狂的问题!!!我有一个用于发送电子邮件的小型 Delphi 7 应用程序(使用 Indy 9 组件套件)并且一切正常。我正在尝试开发一个执行相同操作的 C# 应用程序 (Visual
我的 Smtpclient 正在使用以下设置 SmtpClient client = new SmtpClient(); client.Host = server; client.UseDefault
我的问题是:我需要发现一个 IP 和端口是否正在运行 SMTP 服务。为此,我使用 SMTPClient 尝试打开连接。我正在使用下面的代码。 private static boolean v
我有一个指向我公司邮件服务器的 SmtpClient。我能够成功地向/从该域上的地址发送电子邮件。 但是,我需要为应用程序的用户重置密码和通知。这些用户使用他们自己的电子邮件地址(多个不同的域)注册。
SmtpClient 发送方法返回无效。有什么办法可以得到服务器响应吗?我是否只是假设它是成功的,除非它抛出异常? 我指的是类... http://msdn.microsoft.com/en-us/l
我正在创建每 5 分钟发送一批电子邮件的 Windows 服务。 我想每 5 分钟发送 10-100 封电子邮件。这是极端情况。每 5 分钟发送一次批处理,通常最多包含 10 封电子邮件。 我正在使用
我已经设置了 SmtpClient 类的超时属性,但它似乎不起作用,当我给它一个 1 毫秒的值时,执行代码时超时实际上是 15 秒。我从 msdn 中获取的代码. string to = "jane@
我正在从 Java 向我们的客户发送电子邮件。而且我们的 SMTP 没有任何身份验证。因此,我在 Java 中使用以下代码无需身份验证即可发送: Properties props = new Prop
我有一个 C# 服务 那个连续运行 使用用户凭据(即不是本地系统 - 虽然我想更改但我无法更改)。在大多数情况下,该服务似乎运行正常,但它经常爆炸和 无故重启 (服务管理器设置为在崩溃时重新启动服务)
我是一名优秀的程序员,十分优秀!