Эффективность таймера

Я планирую разработать систему с десятками тысяч объектов в ней, каждый из которых будет иметь до 42 (но, скорее всего, около 4 или 5) отдельных действий, которые они потенциально будут выполнять через регулярные промежутки времени. Я также планирую написать код, который будет отключать таймеры до тех пор, пока объект не начнет использоваться. В режиме ожидания для каждого объекта потребуется только по 1 таймеру, но когда он активен, все остальные таймеры будут запускаться одновременно. Сначала количество объектов будет небольшим, может быть, несколько сотен, но я ожидаю, что оно будет расти экспоненциально, а через несколько месяцев начнёт достигать десятков тысяч.

Итак, Меня очень беспокоит эффективность кода, который я буду писать для таймеров и для этих объектов. Есть три уровня, на которых я мог бы написать это приложение, которое бы все успешно выполняло требуемые задачи. Кроме того, я планирую запустить эту систему на сервере Quad Core, поэтому я хотел бы использовать многопоточность везде, где это возможно.

С этой целью я решил использовать класс System.Timers.Timer, который запускается новый поток для каждого истекшего события.

Я рассматриваю следующие 3 уровня:

  1. Один единственный таймер управляет всем приложением, он выполняет итерацию по каждому объекту, проверяет, нужно ли запускать какие-либо другие действия, и если да, запускает их, а затем переходит к следующему.

  2. Многоуровневый таймер, в котором каждый объект имеет главный таймер, который проверяет все функции, которые может потребоваться выполнить объекту, запускает все готовые, а затем устанавливает следующий интервал таймера равным следующему требуемому времени действия.

  3. Таймер рекурсивного уровня, в котором каждое действие в каждом объекте имеет свой собственный таймер, который будет запускаться, а затем устанавливается для запуска в следующий раз, когда оно станет доступным.

Проблема с вариантом 1 заключается в том, что при таком большом количестве объектов и действий один единичный таймер, истекший таким образом, может работать, может быть, более 20 секунд (в то время как он выполнял несколько миллионов строк зацикленного кода), где это, вероятно, должно быть 1 секунда. Если объекты не будут синхронизироваться, система, скорее всего, не будет работать должным образом.

Проблема с вариантом 2 состоит в том, что его будет немного сложнее написать, чем с вариантом 3, но не намного, это также может означать, что 10 000+, возможно, таймеров, запущенных в системе (по одному для каждого объекта), создающих и уничтожающих потоки с каждым прохождением, как будто его никто ' бизнес (в чем я не уверен, проблема это или нет). В этой ситуации каждый таймер должен срабатывать не реже одного раза в секунду, возможно, при выполнении нескольких сотен строк кода (возможно, до тысячи в крайнем случае).

Проблема с вариантом 3 заключается в огромном количестве таймеров. которые потенциально могут быть введены в систему. Я говорю о среднем 10 000+ таймеров с возможностью одновременного запуска около 100 000+ таймеров. Однако каждое событие elapse может запускать не более 50 строк кода, что делает их очень короткими. У прошедших событий будут задержки от сотой доли секунды на одном полюсе до пяти минут на другом, со средней вероятностью около 1 секунды.

Я хорошо владею Visual Basic .NET и планировал написать его в этом, но я мог бы также вернуться к своим школьным дням и попытаться написать это на C ++ для повышения эффективности, если это будет иметь такое большое значение (пожалуйста, дайте мне знать, есть ли у вас какие-либо источники по эффективности кода между языками). Также играю с идеей запустить это на кластерном сервере Linux вместо моего четырехъядерного сервера Windows, но я не уверен, смогу ли я заставить какое-либо из моих .NET-приложений работать в таком кластере Linux (хотел бы любую информацию

Главный вопрос, на который нужно ответить по этой теме:

Я использую вариант 1, 2 или 3 и почему?

~ Редактировать после рассмотрения комментариев ~

Итак, 4-й вариант с колесом таймера со спин-блокировкой. Вот класс задания:

Public Class Job
Private dFireTime As DateTime
Private objF As CrossAppDomainDelegate
Private objParams() As Object

Public Sub New(ByVal Func As CrossAppDomainDelegate, ByVal Params() As Object, ByVal FireTime As DateTime)
    objF = Func
    dFireTime = FireTime
    objParams = Params
End Sub

Public ReadOnly Property FireTime()
    Get
        Return dFireTime
    End Get
End Property

Public ReadOnly Property Func() As CrossAppDomainDelegate
    Get
        Return objF
    End Get
End Property

Public ReadOnly Property Params() As Object()
    Get
        Return objParams
    End Get
End Property
End Class

И затем реализация основного цикла:

Private Tasks As LinkedList(Of Job)

Private Sub RunTasks()
    While True
        Dim CurrentTime as DateTime = Datetime.Now            

        If Not Tasks.Count = 0 AndAlso Tasks(0).FireTime > CurrentTime Then
            Dim T As Job = Tasks(0)
            Tasks.RemoveFirst()
            T.Func.Invoke()
        Else
            Dim MillisecondDif As Double

            MillisecondDif = Tasks(0).FireTime.Subtract(CurrentTime).Milliseconds
            If MillisecondDif > 30 Then
                Threading.Thread.Sleep(MillisecondDif)
            End If
        End If

    End While
End Sub

Я правильно понимаю?

EpicClanWars.com

~ Редактировать 2 ~

Заменил слово "Задача" на " Работа » так что ppl может перестать жаловаться на это;)

~ Edit 3 ~

Добавлены переменные для отслеживания времени и обеспечения выполнения циклов при необходимости

5
задан Jrud 1 November 2010 в 20:43
поделиться