Исключения не получаются в вызывающей стороне при использовании ASYNC - PullRequest
0 голосов
/ 31 мая 2018

Я использую DispatcherTimer для обработки метода в указанный интервал времени

dispatcherTimer = new DispatcherTimer()
{
   Interval = new TimeSpan(0, 0, 0, 1, 0)
};
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);

Вот метод dispatcherTimer_Tick

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    try
    {
        Task.Run(() => MethodWithParameter(message));
    }
    catch (Exception ex)
    {        
    }
}

Здесь я звоню MQTTPublisher которая является ссылкой на DLL.

private async static void MethodWithParameter(string message)
{
    try
    {
        await MQTTPublisher.RunAsync(message);    
    }
    catch (Exception Ex)    
    {       
    }            
}

Я не могу отловить исключения, которые выбрасываются в эту DLL.Как я могу получить исключение для вызывающей стороны?

Определение RunAsync - это в отдельной dll.

public static async Task RunAsync(string message)
{
    var mqttClient = factory.CreateMqttClient();
    //This creates MqttFactory and send message to all subscribers
    try
    {
        await mqttClient.ConnectAsync(options);        
    }
    catch (Exception exception)
    {
        Console.WriteLine("### CONNECTING FAILED ###" + Environment.NewLine + exception);
        throw exception;
    }
}

И

Task<MqttClientConnectResult> ConnectAsync(IMqttClientOptions options)

1 Ответ

0 голосов
/ 31 мая 2018

Это недостаток использования async void.Измените свой метод, чтобы он возвращал async Task вместо:

private async static Task MethodWithParameter(string message)
{
    try
    {
        await MQTTPublisher.RunAsync(message);

    }
    catch (Exception Ex)    
    {

    }            
}

На основе: Асинхронное / ожидающее - лучшие практики в асинхронном программировании

Асинхронные пустые методы имеютдругая семантика обработки ошибок.Когда исключение выбрасывается из метода асинхронной задачи или асинхронной задачи, это исключение захватывается и помещается в объект задачи.При использовании асинхронных void-методов объект Task отсутствует, поэтому любые исключения, выбрасываемые из асинхронного void-метода, будут вызываться непосредственно в SynchronizationContext, который был активен при запуске асинхронного void-метода.

And:

Рисунок 2 Исключения из метода асинхронной пустоты невозможно обнаружить с помощью Catch

private async void ThrowExceptionAsync()
{
    throw new InvalidOperationException();
}

public void AsyncVoidExceptions_CannotBeCaughtByCatch()
{
    try
    {
        ThrowExceptionAsync();
    }
    catch (Exception)
    {
        // The exception is never caught here!
        throw;
    }
}
...