【问题标题】:Exception handling during the multiple asynchronous method call is not working多个异步方法调用期间的异常处理不起作用
【发布时间】:2018-06-09 12:29:17
【问题描述】:

我每秒生成超过 100 条消息,并在单独的线程中发送这些消息。当连接断开时,我想在调用者中捕获异常。由于我的所有消息都是异步发送的,因此我无法捕获异常。

这是调用dispatcherTimer_Tick方法的DispatcherTimer代码

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


private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    try
    {
        item = "some generated message";
        Task.Run(() => SendMessage(item));                  
    }
    catch (Exception)
    {

    }
}

这是SendMessage 代码。我通过阅读基于:Async/Await - Best Practices in Asynchronous Programming 进行了更改,但它不起作用

private async static Task SendMessage(string message)
{
    try
    {
        (MQTT.RunAsync(message.ToString(), topic)).Wait();                
    }
    catch (Exception Ex)    
    {
        // Exceptions are not getting cought here
    }
}

MQTT.RunAsync 的定义

public static async Task RunAsync(string message)
{
    var mqttClient = factory.CreateMqttClient()               
    try
    {
        await mqttClient.ConnectAsync(options);
    }
    catch (Exception exception)
    {

    }
}

还有

Task<MqttClientConnectResult> ConnectAsync(IMqttClientOptions options)

更新问题

我的RunAsync 首先尝试连接,如果成功则发送消息。所以我不能在连接检查时写return

 public Task RunAsync(string message, string topicName)
    {

            this.mqttClient.ConnectAsync(this.options);
            mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(this._topicname).WithExactlyOnceQoS().Build());
            var applicationMessage = new MqttApplicationMessageBuilder().WithTopic(this._topicname)
               .WithPayload(message).WithAtLeastOnceQoS().Build();

            if (stopSending == false)
            {
                return mqttClient.PublishAsync(applicationMessage);
            }
            return null;
    }

【问题讨论】:

  • 您是否尝试过在 MQTT.RunAsync 中从 RunAsync 抛出异常?
  • 是的,这会破坏应用程序。我写道,抛出异常。
  • 我觉得 AppDomain.UnhandledException 事件是解决办法。

标签: c# multithreading mqtt


【解决方案1】:

事件处理程序是允许async void 的例外

private async void dispatcherTimer_Tick(object sender, EventArgs e) {
    try {
        item = "some generated message";
        await SendMessage(item);
    } catch (Exception ex) {
        //...handle exception
    }
}

此外,您似乎正在以任何方式使用异常,因为它已经被进一步捕获到堆栈中。

尽量保持代码异步,不要混用像.Wait().Result这样的阻塞调用

private static Task SendMessage(string message) {
    return MQTT.RunAsync(message, topic);
}

public static async Task RunAsync(string message, string topicName) {
    await this.mqttClient.ConnectAsync(this.options);
    var topicFilter = new TopicFilterBuilder().WithTopic(this._topicname)
        .WithExactlyOnceQoS().Build();
    await mqttClient.SubscribeAsync(topicFilter);
    var applicationMessage = new MqttApplicationMessageBuilder().WithTopic(this._topicname)
       .WithPayload(message).WithAtLeastOnceQoS().Build();

    if (stopSending == false) {
        await mqttClient.PublishAsync(applicationMessage);
    }

}

【讨论】:

  • 看起来不错,但我的 RunAsync 并不简单。我现在已经提出了整个 RunAsync 方法的问题。我不能在 RunAsync 中使用“return”进行连接检查。即使连接检查也可能抛出异常
  • 仍然没有抛出异常!
  • 已解决。我们不应该尝试 catch :) 并且需要使用 TaskSchedulerOnUnobservedTaskException 处理程序 :)
猜你喜欢
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 1970-01-01
相关资源
最近更新 更多