[英]call async in non async method and log exceptions for the async await method
假設我的服務正在運行,並且我已使用代碼在該服務中發送電子郵件通知。 “EmailNotification”方法是異步並等待。
電子郵件通知代碼:
public async task EmailNotification()
{
try
{
//code here
using (SmtpClient smtp = new SmtpClient())
{
//mail sending
await smtp.Send(mailMessage);
}
}
Catch(Exception ex)
{
}
}
在我的一些測試方法中使用的EmailNotification方法如下:
public void test()
{
EmailNotification();
}
我的問題:
1)如果我的目標方法測試不是async類型,我如何記錄async和await方法的execptions?
2)是否可以在非同步類型中使用異步方法,如在測試方法中使用?
如果我的目標方法測試不是async類型,我如何記錄async和await方法的execptions?
從async
方法返回的任務將包含該方法的任何異常。 但是,以“即發即忘”的方式調用它,例如這意味着忽略返回的任務。 因此,您必須在async
方法(已經存在)中使用try
/ catch
並登錄catch
。
是否可以在非同步類型中使用async方法,如上所述,在測試方法中使用?
可能? 當然,它會編譯運行。
一個好主意? 可能不是。
在ASP.NET上,不保證在HTTP請求之外完成的任何工作都可以完成。 當您的代碼調用EmailNotification
,它會開始一些工作,然后完成HTTP請求(通過發送響應)。 然后,在沒有HTTP請求的情況下完成發送電子郵件工作,如果您的應用程序被回收,則可能會丟失。
這是一個很好的方法,如果你完全沒有電子郵件偶爾消失沒有任何日志或任何其他指標出錯。 如果您對此不滿意,那么您將需要一個更強大的解決方案(例如我在博客上描述的適當的分布式架構 )。 或者您可以通過使用SendGrid等電子郵件服務將其中的一部分外包出去。
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已經在這個問題中得到了很好的答案: 如何從C#中的同步方法調用異步方法? (我的代碼基於)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.