C#异步任务-MANDRILL API
本文关键字:API -MANDRILL 任务 异步 | 更新日期: 2023-09-27 18:22:03
我正在为我们的内部系统设置Mandrill Api。
我可以让API正常工作,并可以从中接收电子邮件,我的问题是,当我尝试从发送请求中获得结果时,系统会无限期挂起。
我的代码如下:
public async Task<bool> SendEmail(MandrillSendTemplateRequest request)
{
var result = await _mandrill.SendMessageTemplate(Map(request));
return result[0].Status.ToString() == "sent";
}
如果我在没有返回的情况下运行上面的代码,那么电子邮件会发送罚款。如果我运行上面的代码并返回,那么电子邮件发送良好,但我的程序只是挂起。
有人能阐明这个问题吗?
编辑。作为参考,我使用的是NuGet Packages的Shawn Mclean的Mandrill.Net Wrapper。Mandrill API 2.2.7
编辑。调用SendEmail方法的按钮点击事件:
Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
Try
WaitCursor = True
Dim mgr As New CustomerCommunicationsManager()
Dim r As New MandrillSendTemplateRequest()
Dim m As New MandrillMessage()
m.FromEmail = "from@icloud.com"
m.FromName = "fromName"
m.Subject = "Test"
m.ForeName = "Software"
m.Surname = "Dept"
m.EmailAddress = "software@icloud.com"
r.Message = m
r.TemplateName = "WelcomeBasic"
Dim sent As Boolean = mgr.Mandrill.SendEmail(r).Result
Catch ex As Exception
Finally
WaitCursor = False
End Try
End Sub
编辑。地图代码(请求)(发送电子邮件方式)
private SendMessageTemplateRequest Map(MandrillSendTemplateRequest obj)
{
if (obj == null) { return null; }
return new SendMessageTemplateRequest(Map(obj.Message), obj.TemplateName, Map(obj.TemplateContent));
}
private EmailMessage Map(MandrillMessage obj)
{
if (obj == null) { return null; }
return new EmailMessage
{
AutoHtml = obj.AutoHtml,
AutoText = obj.AutoText,
FromEmail = obj.FromEmail,
FromName = obj.FromName,
Important = obj.Important,
PreserveRecipients = obj.PreserveRecipients,
Subject = obj.Subject,
Tags = obj.tags,
To = new EmailAddress[] { new EmailAddress(obj.EmailAddress, obj.FullName) },
TrackOpens = obj.TrackOpens,
TrackClicks = obj.TrackClicks
};
}
private IEnumerable<TemplateContent> Map(IEnumerable<MandrillTemplateContent> obj)
{
if (obj == null) { return null; }
List<TemplateContent> content = new List<TemplateContent>();
foreach (MandrillTemplateContent c in obj)
{
content.Add(new TemplateContent{ Content = c.Content, Name = c.Name });
}
return content;
}
您有一个死锁,因为您在UI线程的上下文中阻塞了异步方法。你不应该阻止异步代码,你应该等待它:
Private Async Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click
...
Dim sent As Boolean = Await mgr.Mandrill.SendEmail(r)
End Sub
UI线程有一个SynchronizationContext
(您可以看到SynchronizationContext.Current != null
),它确保等待后的代码被发布到单个UI线程。
由于您使用Task.Result
阻塞了UI线程,等待之后的代码无法运行,这意味着任务无法完成,因此UI线程将永远阻塞。
您可以通过告诉等待者不要使用ConfigureAwait(false)
捕获SynchronizationContext
来减轻这种情况,但尽管这是一个很好的做法,但您不应该一开始就阻止:
public async Task<bool> SendEmailAsync(MandrillSendTemplateRequest request)
{
var result = await _mandrill.SendMessageTemplate(Map(request)).ConfigureAwait(false);
return result[0].Status.ToString() == "sent";
}