C# - Как получить доступ к переменной уровня класса из события истекшего таймера в многопоточном классе - PullRequest
0 голосов
/ 19 июня 2020

У меня есть класс с timer, по истечении таймера мне нужно проверить переменную уровня класса _isModelShutdown, чтобы определить, вызывать ли событие или нет. Проблема в том, что таймер не может получить последнее значение из переменной уровня класса _isModelShutdown. Я попробовал изменить эту переменную на переменную static, но это не решило мою проблему, потому что этот класс вызывается несколькими потоками. Итак, когда я нахожусь в таймере, переменная, кажется, получает значение по умолчанию false вместо true, которое было установлено событием Consumer_Channel_ModelShutdown, говорящим о завершении работы. Я думаю, что другой поток уже обновил переменную stati c до false.

Рабочий процесс: когда происходит отключение канала, запускается Consumer_Channel_ModelShutdown, что устанавливает _isModelShutdown=true. Таймер должен проверить наличие _isModelShutdown==true, чтобы вызвать событие Channel_Failure. Причина, по которой я не могу сделать все это в событии Consumer_Channel_ModelShutdown, заключается в том, что RabbitMQ сообщает, что обратный вызов выключения не является безопасным местом для открытия другого канала, поскольку он вызывает ошибку тайм-аута в коде создания канала. Надеюсь, это проясняет проблему.

public class SomeClass
{
    public event Func<string> Channel_Failure;
    IModel consumerChannel = null;
    private static bool _isModelShutdown = false;
    public SomeClass(RabbitMQConnectionInfo rabbitMQConnectionInfo, Func<string> handleFailure)
    {
        if (handleFailure != null)
        {
           Channel_Failure = handleFailure;
        }
        consumerChannel = rabbitMQConnectionInfo.Connection.CreateModel();
        // Some more code
        if (connected) return;
        StartTimer((int)reconnectionInterval);
    }

    private void StartTimer(int waitIntervalBeforeReconnecting)
    {
        double interval = 30000;
        var retryTimer = new Timer(interval)
        {
            AutoReset = true //run once
        };
        retryTimer.Elapsed += (sender, eventArgs) =>
        {
            RetryTimerElapsed((Timer)sender);
        }
        retryTimer.Start();
    }

    private void RetryTimerElapsed(IDisposable sender)
    {
       if (_isModelShutdown) // This is the problem statement, how to access class level variable??
       {
           Channel_Failure?.Invoke(source);
           _isModelShutdown = false; 
       }
    }

    private void Consumer_Channel_ModelShutdown(object sender, Client.ShutdownEventArgs reason)
    {
        _isModelShutdown = true;
    }
}

Есть ли лучший способ справиться с этим сценарием, любая помощь будет принята с благодарностью.

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