динамическое использование объектов таймера c # /. net - PullRequest
1 голос
/ 30 августа 2011

Я хотел посмотреть, есть ли у кого-нибудь опыт или советы по динамическому использованию таймеров. Нам нужен сервис Windows, который будет периодически проверять текстовый файл. Текстовый файл будет содержать название рынка и время начала. Затем службе необходимо создать таймер для выполнения обратного отсчета и записать информацию об обратном отсчете в XML-файл ... например, 23 минуты

теперь все это работает в приложении для Windows для одного таймера и одного обратного отсчета ... теперь мы хотим сделать это динамическим ...

поэтому, когда служба запускается, она создаст таймер для каждого рынка / времени обратного отсчета ... (опыт Феникс 10:00, Чикаго 23:45 и т. Д.).

Затем служба проверит этот текстовый файл на наличие любых НОВЫХ записей ... Так что, если в файл добавлены «Феникс», «Чикаго», а затем добавлен «Нью-Йорк», мы бы хотели, чтобы служба поддерживала работу таймеров «Феникс» и «Чикаго», а затем запускали таймер для Нью-Йорка.

Я просто не уверен, как будут работать несколько таймеров, работающих в службе, и как будут работать потоки, когда им всем нужно записать в один и тот же XML-файл.

есть мысли по этому поводу?

Ответы [ 2 ]

2 голосов
/ 30 августа 2011

Я просто не уверен, как будут работать несколько таймеров, работающих в службе, и как будут работать потоки, когда им всем нужно записать в один и тот же XML-файл.

есть мысли по этому поводу?

Это не сработает.

Таймеры ставятся в очередь в пул потоков. Пул потоков будет создавать только определенное количество активных потоков одновременно:

http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

Количество операций, которые могут быть поставлены в очередь в пуле потоков, ограничено только доступной памятью; однако пул потоков ограничивает число потоков, которые могут быть активны в процессе одновременно

Кроме того, запись в один и тот же файл из нескольких потоков приведет к плохим результатам.

Не говоря уже о том, что будет гораздо сложнее выяснить, что делает ваше приложение, если у вас запущены все эти потоки.

Более простой подход

Возьмите существующий таймер и создайте свою собственную систему синхронизации, которая не использует потоки.

  • Создать структуру, определяющую запись обратного отсчета.

Код:

public class Countdown
{
    public DateTime Time { get; set; }
    public event Action Elapsed { get; set; }

    public void RaiseElasped()
    {
        if(Elapsed != null)
            Elapsed();
    }
}
  • Прочитайте ваш файл и создайте: Dictionary<string, Countdown> (имя -> обратный отсчет). Вставляйте один и тот же код в каждое действие, которое вы собираетесь добавить в таймеры.

  • Создайте FileSystemWatcher для поиска изменений во входном файле. Когда файл запущен, измените словарь по мере необходимости.

  • Создание одного таймера с разрешением в одну минуту.

  • Каждый раз, когда срабатывает таймер, проверяйте каждый элемент в словаре. Если целевое время прошло, позвоните RaiseElapsed. (возможно, удалить его из словаря тоже?)

С этого момента трудно точно определить, что вы хотите сделать, потому что вы не описали, что записывается в файл, когда это происходит, как часто или что происходит после истечения вашего обратного отсчета. Вы должны быть в состоянии выяснить все остальное самостоятельно.

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

Недостаток в том, что он может затормозиться, когда у вас много записей. Но если у вас много записей, вы должны использовать базу данных вместо файлов.

1 голос
/ 30 августа 2011

Вы можете сохранить Dictionary<string,DateTime>, который содержит название рынка и время. С регулярным интервалом (скажем, каждую минуту?) Вы можете сканировать словарь и вычислять истекшее время, просто используя DateTime.Subtract (), и записывать результат в выходной файл. Вы также можете посмотреть на Класс секундомера .

...