使用ASYNC时,呼叫者不会收到例外情况

时间:2018-05-31 05:29:11

标签: c# multithreading asynchronous exception-handling async-await

我正在使用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 :(得分:1)

这是使用async void的缺点。更改您的方法以返回async Task

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

    }
    catch (Exception Ex)    
    {

    }            
}

基于:Async/Await - Best Practices in Asynchronous Programming

  

Async void方法具有不同的错误处理语义。当异步任务或异步任务方法抛出异常时,将捕获该异常并将其放在Task对象上。使用async void方法,没有Task对象,因此异步void方法抛出的任何异常都将直接在async void方法启动时处于活动状态的SynchronizationContext上引发。

  

图2无法使用Catch

捕获Async Void方法的异常
private async void ThrowExceptionAsync()
{
    throw new InvalidOperationException();
}

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