【发布时间】:2019-10-17 14:25:21
【问题描述】:
我正在编写一些 C# 代码来发送电子邮件(通过 Mailjet/Azure)。它确实发送了电子邮件,但由于某种原因,在单步执行代码时,我从来没有通过这行代码......
MailjetResponse response = await client.PostAsync(request);
它只是挂在那个点上。知道为什么吗?再次,电子邮件发送正常!
public static async Task<bool> SendEmailWithAttachment(string toAddress, string subject, string messageBody, bool sendBCCYesNo, bool sendFromInfoAddressYesNo, MemoryStream attachment = null, string attachmentFilename = null)
{
bool successYesNo = true;
try
{
MailjetClient client = new MailjetClient("xxxxxx", "xxxxx")
{
Version = ApiVersion.V3_1,
};
MailjetRequest request = new MailjetRequest
{
Resource = Send.Resource,
}
.Property(Send.Messages, new JArray {
new JObject {
{"From", new JObject {
{"Email", "xxxxx@xxxxx.com"},
{"Name", "xxxxx"}
}},
{"To", new JArray {
new JObject {
{"Email", toAddress},
{"Name", toAddress}
}
}},
{"Subject", subject},
{"TextPart", messageBody},
{"HTMLPart", messageBody}
}
});
MailjetResponse response = await client.PostAsync(request);
if (response.IsSuccessStatusCode) // I never get to this point
{
:
我正在使用这个来调用代码......
if (Utility.SendEmailWithAttachment("xxxxx@xxxxx.com", "Test Email", "Test Body", false, false,
po, "AAA.pdf").Result == false)
{
lblStatus.Text = "Email send failure. Please contact support.";
return false;
}
有趣的是,当我运行 mailjet 提供的示例代码时,我的电子邮件发送正常,并且我确实在 PostAsync 之后到达了该行。据我所知,唯一的主要区别是我使用的是返回布尔值的任务,而不仅仅是任务。这是 mailjet 提供的代码,可以正常工作....
static void Main(string[] args)
{
RunAsync().Wait();
}
static async Task RunAsync()
{
MailjetClient client = new MailjetClient("xxxx", "xxxx")
{
Version = ApiVersion.V3_1,
};
MailjetRequest request = new MailjetRequest
{
Resource = Send.Resource,
}
.Property(Send.Messages, new JArray {
new JObject {
{"From", new JObject {
{"Email", "xxxx@xxxx.com"},
{"Name", "xxxx"}
}},
{"To", new JArray {
new JObject {
{"Email", "xxxx@xxxx.com"},
{"Name", "xxxx"}
}
}},
{"Subject", "Your email flight plan!"},
{"TextPart", "Dear passenger 1, welcome to Mailjet! May the delivery force be with you!"},
{"HTMLPart", "<h3>Dear passenger 1, welcome to <a href='https://www.mailjet.com/'>Mailjet</a>!</h3><br />May the delivery force be with you!"}
}
});
MailjetResponse response = await client.PostAsync(request);
if (response.IsSuccessStatusCode) // this line is reached!
{
提前致谢!
【问题讨论】:
-
@StasIvanov 我更新了操作。
-
@AhmedMsaouri 不,它没有。
await不会启动或运行任何东西,它等待一个已经在运行的操作而不阻塞调用线程。 -
@WebDevGuy2 首先删除所有阻塞调用,如
.Result或.Wait(),并改用await。.Result块。如果您在 UI 线程上执行此操作,则应用程序本身会阻塞。这意味着任何其他正在等待的异步操作将无法在 UI 线程上恢复 -
@WebDevGuy2 你在哪里打电话给
if (Utility.SendEmailWithAttachment...?呼叫至少应更改为if (await SendEmailWithAttachment(..))。该方法应标有async。如果这是一个事件处理程序,它应该是async void。 任何其他方法都应该使用async Task。 -
@WebDevGuy2 现在,
.Result阻塞了 UI 线程。对await client.PostAsync(request);的调用将尝试在该线程上恢复,该线程已被阻塞,从而导致死锁。只需删除.Result并改用await将删除死锁 并 允许 UI 响应其他事件。在SendEmailWithAttachment中使用ConfigureAwait(false)意味着await不会尝试在UI 线程上恢复——这也将防止死锁但不会释放UI 线程。
标签: c# multithreading async-await task mailjet