在非异步方法中调用异步并为异步等待方法记录异常
假设我的服务正在运行,并且我使用了用于在该服务中发送电子邮件通知的代码。 “EmailNotification”方法是异步并等待。在非异步方法中调用异步并为异步等待方法记录异常
代码EmailNotification的:
public async task EmailNotification()
{
try
{
//code here
using (SmtpClient smtp = new SmtpClient())
{
//mail sending
await smtp.Send(mailMessage);
}
}
Catch(Exception ex)
{
}
}
使用EmailNotification methos在我的一些测试方法类似:
public void test()
{
EmailNotification();
}
我的问题:
1)如何我记录async和a的错误等待方法,如果我的目标方法测试不是类型异步?
2)是否有可能在非异步类型中使用异步方法,如上面ia m在测试方法中使用的那样?
public static class TaskExtensions
{
/// <summary>
/// Waits for the task to complete, unwrapping any exceptions.
/// </summary>
/// <param name="task">The task. May not be <c>null</c>.</param>
public static void WaitAndUnwrapException(this Task task)
{
task.GetAwaiter().GetResult();
}
/// <summary>
/// Waits for the task to complete, unwrapping any exceptions.
/// </summary>
/// <param name="task">The task. May not be <c>null</c>.</param>
public static T WaitAndUnwrapException<T>(this Task<T> task)
{
return task.GetAwaiter().GetResult();
}
}
,然后用它是这样的:
try
{
var t = EmailNotification();
t.WaitAndUnwrapException();
}
catch(Exception ex)
{
// log...
}
或者:
public void test()
{
try
{
var t = EmailNotification();
t.GetAwaiter().GetResult();
}
catch(Exception ex)
{
// Do your logging here
}
}
你应该总是尝试使用await
/async
一路,并尽可能避免这种模式。但是,当您需要从非异步方法调用异步方法时,可以使用GetAwaiter().GetResult()
来等待任务并获取正确的异常(如果有)。
正如在评论中提到有这个问题已经是一个很好的答案,从Stephen Cleary: How to call asynchronous method from synchronous method in C#?(其中我的代码是基于)
所以为了在非异步方法“Test”中使用异步方法“EmailNotification”,我必须创建一个类“TaskExtensions”并在我的notifiaction方法之后调用方法“WaitAndUnwrapException”..这种方法会在运行时记录异常服务?? – stylishCoder
我已经更新了我的答案。扩展点在于它将解包异步方法中引发的任何异常。您仍然需要手动记录它。 – smoksnes
谢谢@smoksnes我会尝试this.let的c。 – stylishCoder
我怎么能登录的异步execptions如果我的目的方法await方法测试不是类型异步?
从async
方法返回的任务将包含该方法的任何异常。然而,像这样以“失火和忘记”的方式来调用它意味着返回的任务被忽略。因此,您必须在async
方法(已存在)中登记try
/catch
并登录catch
。
是否有可能在非异步类型中使用异步方法如上面ia m在测试方法中使用?
可能吗?当然,它会编译并运行。
一个好主意?可能不会。
在ASP.NET上,任何已完成的工作以外的都不能保证完成HTTP请求。当你的代码调用EmailNotification
时,它是开始的一些工作,然后完成HTTP请求(通过发送响应)。该发送电子邮件工作在没有HTTP请求的情况下完成,并且如果您的应用程序被回收,则可能会丢失。
如果您完全确定电子邮件偶尔会消失,而没有任何日志或任何其他指示器出现问题,那么这是一个很好的方法。如果您不满意,那么您需要一个更强大的解决方案(例如我在博客中描述的proper distributed architecture)。或者,您可以使用SendGrid等电子邮件服务将该部分外包。
[如何从C#中的同步方法调用异步方法?]可能的重复?(http://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in- c) – prospector