使用 ASYNC 时调用方未收到异常

Exceptions are not received in caller when using ASYNC

我正在使用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)

这是使用 async void 的缺点。将您的方法改为 return 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 methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started.

并且:

Figure 2 Exceptions from an Async Void Method Can’t Be Caught with Catch

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

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