2016-06-13 168 views
0

假設我的服務正在運行,並且我使用了用於在該服務中發送電子郵件通知的代碼。 「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

回答

1
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

2

我怎麼能登錄的異步execptions如果我的目的方法await方法測試不是類型異步?

async方法返回的任務將包含該方法的任何異常。然而,像這樣以「失火和忘記」的方式來調用它意味着返回的任務被忽略。因此,您必須在async方法(已存在)中登記try/catch並登錄catch

是否有可能在非異步類型中使用異步方法如上面ia m在測試方法中使用?

可能嗎?當然,它會編譯並運行。

一個好主意?可能不會。

在ASP.NET上,任何已完成的工作以外的都不能保證完成HTTP請求。當你的代碼調用EmailNotification時,它是開始的一些工作,然後完成HTTP請求(通過發送響應)。該發送電子郵件工作在沒有HTTP請求的情況下完成,並且如果您的應用程序被回收,則可能會丟失。

如果您完全確定電子郵件偶爾會消失,而沒有任何日誌或任何其他指示器出現問題,那麼這是一個很好的方法。如果您不滿意,那麼您需要一個更強大的解決方案(例如我在博客中描述的proper distributed architecture)。或者,您可以使用SendGrid等電子郵件服務將該部分外包。