2016-06-13 2 views
0

Предположим, что моя служба запущена, и я использовал код для отправки уведомлений по электронной почте в этой службе. Метод «EmailNotification» асинхронный и ожидает.вызывать async в методе non async и исключениях журнала для метода ожидания async

Код 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) Как можно i log execptions async и метод ожидания, если мой метод метода назначения не относится к типу async?

2) Можно ли использовать метод async в неасинхронном типе, как указано выше, в методе тестирования?

+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 весь путь, и избежать этого шаблона, когда это возможно. Но когда вам нужно вызвать метод async из метода non-async, вы можете использовать GetAwaiter().GetResult(), чтобы ждать задания, а также получить правильное Исключение (если оно есть).

Как уже упоминалось в комментариях есть уже отличный ответ от Stephen Cleary в этом вопросе: How to call asynchronous method from synchronous method in C#? (который мой код основан на)

+0

поэтому для того, чтобы использовать метод асинхронизации «EmailNotification» в неасинхронном режиме «Тест», мне нужно создать класс «TaskExtensions» и вызвать метод «WaitAndUnwrapException» после моего метода notifiaction .. этот метод регистрирует исключение при запуске оказание услуг?? – stylishCoder

+0

Я обновил свой ответ. Точка с расширениями состоит в том, что она разворачивает любые Исключения, которые выбрасываются в методе async. Вам все равно придется регистрировать его вручную. – smoksnes

+0

Спасибо @smoksnes, я попробую this.let's c. – stylishCoder

2

Как я могу войти execptions из асинхронной и ждать метод, если мой метод назначения Тест не относится к типу async?

Задача, возвращаемая из метода async, будет содержать любые исключения из этого метода. Тем не менее, называя его «способом огня и забывания», например, это означает, что возвращенная задача игнорируется. Таким образом, вам нужно будет иметь /catch в вашем методе async (который уже существует) и войдите в систему catch.

Можно ли использовать метод async в неасинхронном типе, таком как выше ia m, используя метод тестирования?

Возможно ли? Конечно, он будет компилироваться и запускаться.

Хорошая идея? Возможно нет.

На ASP.NET любая выполненная работа за пределами HTTP-запроса не может быть завершена. Когда ваш код вызывает EmailNotification, это , начиная с, а затем выполняет HTTP-запрос (отправив ответ).Эта работа с электронной почтой выполняется без HTTP-запроса и может быть потеряна, если ваше приложение переработано.

Это прекрасный подход, если вы отлично справляетесь с исчезновением писем, иногда без каких-либо журналов или других индикаторов, что что-то пошло не так. Если вы не в порядке с этим, тогда вам понадобится более надежное решение (например, proper distributed architecture, как я расскажу в своем блоге). Или вы можете просто передать его на аутсорсинг, используя почтовую службу, такую ​​как SendGrid.

Смежные вопросы