Обработка исключений во время многократного асинхронного вызова метода не работает - PullRequest
0 голосов
/ 09 июня 2018

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

Вот код DispatcherTimer, который вызывает метод dispatcherTimer_Tick

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.Я внес изменения, прочитав Основано на: Асинхронное / ожидание - Лучшие практики асинхронного программирования , НО это не работает

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;
    }

1 Ответ

0 голосов
/ 09 июня 2018

Обработчики событий являются исключением, где разрешено 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);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...