Таймер C # и безопасность потоков - PullRequest
1 голос
/ 19 марта 2011

У меня есть класс C # с массивом объектов, каждый объект представляет открытое соединение с внешним устройством. По умолчанию время соединения истекает через n часов простоя, которых я хочу избежать. Я планирую использовать таймер, который отключается каждые n-2 часа простоя, с обратным вызовом, который вызывает метод для прикосновения к каждому объекту и эффективного сброса времени ожидания.

Класс должен быть применим как в формах Windows, так и в проектах, не основанных на формах, поэтому я рассматриваю возможность использования System.Timers.Timer и блокировки, чтобы ограничить доступ любого другого потока к массиву во время сброса времени ожидания.

Использование таймера приводит к последствиям для безопасности потока, например, если один из объектов будет разрушен между обратным вызовом таймера, определяющим, что объект существует и сбрасывающим его время ожидания, будет предпринята попытка прочитать неинициализированную память. Тем не менее, моя проблема заключается в том, что доступ к массиву в нескольких местах в классе. Блокировка должна блокировать любой доступ к массиву во время выполнения обратного вызова таймера следующим образом:

class MyClass
{
    private System.Timers.Timer timer;
    private object locker = new object();

    public void Run()
    {
        timer = new System.Timers.Timer();
        timer.Interval = 21600000;  //6 hours
        timer.Elapsed += AccessArrayCallback;
        timer.Start();
    }

    public void AccessArrayCallback(object sender, EventArgs e)
    {

        timer.Enabled = false;
        lock (locker)
        {
            /*  

            if (called by timer) 
            {  
                iterate through array and reset connections;
            }
            else 
            {
                Call appropriate function that reads/writes array using EventArgs delegate   
            }

            */
        }
        timer.Enabled = true;

    }
}

Несколько вопросов, прежде чем я продолжу этот подход:

  1. Существует ли установленная модель / более элегантный подход к решению этой проблемы?

  2. Правильно ли использовать делегат в EventArgs? Любой другой метод в классе, требующий доступа к массиву, будет вызывать обратный вызов и заполнять EventArgs соответствующим образом.

Заранее спасибо.

1 Ответ

3 голосов
/ 19 марта 2011

Поскольку блокировка является частным объектом, другая часть системы не сможет получить к нему доступ, чтобы достичь желаемого уровня безопасности потоков. Вот почему Concurrent Bag и его друзья были созданы. Часть делегата, если хорошо, хотя.

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