在非异步方法中调用异步并为异步等待方法记录异常

问题描述:

假设我的服务正在运行,并且我使用了用于在该服务中发送电子邮件通知的代码。 “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在测试方法中使用的那样?

+0

[如何从C#中的同步方法调用异步方法?]可能的重复?(http://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in- c) – prospector

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 ClearyHow to call asynchronous method from synchronous method in C#?(其中我的代码是基于)

+0

所以为了在非异步方法“Test”中使用异步方法“EmailNotification”,我必须创建一个类“TaskExtensions”并在我的notifiaction方法之后调用方法“WaitAndUnwrapException”..这种方法会在运行时记录异常服务?? – stylishCoder

+0

我已经更新了我的答案。扩展点在于它将解包异步方法中引发的任何异常。您仍然需要手动记录它。 – smoksnes

+0

谢谢@smoksnes我会尝试this.let的c。 – stylishCoder

我怎么能登录的异步execptions如果我的目的方法await方法测试不是类型异步?

async方法返回的任务将包含该方法的任何异常。然而,像这样以“失火和忘记”的方式来调用它意味着返回的任务被忽略。因此,您必须在async方法(已存在)中登记try/catch并登录catch

是否有可能在非异步类型中使用异步方法如上面ia m在测试方法中使用?

可能吗?当然,它会编译并运行。

一个好主意?可能不会。

在ASP.NET上,任何已完成的工作以外的都不能保证完成HTTP请求。当你的代码调用EmailNotification时,它是开始的一些工作,然后完成HTTP请求(通过发送响应)。该发送电子邮件工作在没有HTTP请求的情况下完成,并且如果您的应用程序被回收,则可能会丢失。

如果您完全确定电子邮件偶尔会消失,而没有任何日志或任何其他指示器出现问题,那么这是一个很好的方法。如果您不满意,那么您需要一个更强大的解决方案(例如我在博客中描述的proper distributed architecture)。或者,您可以使用SendGrid等电子邮件服务将该部分外包。