65 просмотра
1 ответ
370 Репутация автора
Все, я отслеживаю свои почтовые ящики Outlook для некоторых электронных писем и парсингов, основанных на контенте Я делаю это путем запуска консольного приложения и запуска таймера, как показано ниже. Проблема в том, что через некоторое время происходит сборка мусора, и мне приходится перезапускать приложение вручную. Я не могу запустить это в службе Windows, так как я получаю некоторые проблемы с разрешениями при вызове API Outlook. Пожалуйста, смотрите мой код ниже
Я попытался сделать GC.SuppressFinalize (), GC.KeepAlive () для объекта таймера, но безрезультатно.
Ответы (1)
0 плюса
4556 Репутация автора
В рамках вашего примера приложения вы Timer не собираете мусор, поэтому вы должны получить еще одну ошибку. Также, пожалуйста, смотрите мою заметку и пример ниже о GC.SuppressFinalize том, что вы подразумеваете, и что это делает, это две разные вещи.
Петля вместо таймера
Просто предложение: при использовании а Timer и Elapsed событие вызывает таймер для остановки и последующего запуска после завершения, это признак того, что вместо этого вам нужно запустить простой цикл с ожиданием потока.
Поскольку это консольное приложение и другие потоки не требуются, я опубликую простой пример зацикливания, который, IMO, будет более эффективным и простым в управлении.
GC.SuppressFinalize Информация
Кроме того, GC.SuppressFinalize не имеет ничего общего с сборкой мусора; он просто сообщает сборщику мусора, что при сборке не запускать финализатор на объекте (метод деструктора в C #). Это полезно, когда есть элементы, которые уже удалены, и вы не хотите воспроизводить работу . Например, если вы являетесь объектом IDisposable , и вы помещаете Dispose метод в деструктор, и пользователь правильно удаляет его, когда он тогда вы можете пропустить деструктор. Вот пример использования GC.SuppressFinalize правильно.
Пример GC.SuppressFinalize
И просто для показа вот консольное приложение, которое иллюстрирует GC.SuppressFinalize работу. Я делаю 2 IDisposable объекта. Первый я действительно распоряжаться должным образом с using заявлением, а второй я не делаю. Как только они выходят за рамки, они собираются для сбора мусора. Я намеренно вызываю сборщик мусора и жду вызова всех финализаторов, чтобы мы могли сразу увидеть результаты.
Обратите внимание, что удаленный объект НЕ вызывает финализатор, а объект, который не был удален, делает (что, в свою очередь, вызывает dispose . что является правильным способом его реализации).
Только это — как добавить таймер в консольное приложение C #? Было бы здорово, если бы вы могли привести пример кода.
7 ответов
Это очень хорошо, однако, чтобы смоделировать некоторое время, нам нужно запустить команду, которая занимает некоторое время, и это очень ясно во втором примере.
Однако стиль использования цикла for для выполнения некоторой функциональности навсегда требует много ресурсов устройства, и вместо этого мы можем использовать сборщик мусора, чтобы сделать что-то подобное.
Мы видим эту модификацию в коде из той же книги CLR Via C # Third Ed.
Используйте класс System.Threading.Timer.
System.Windows.Forms.Timer предназначен главным образом для использования в одном потоке, обычно в потоке пользовательского интерфейса Windows Forms.
Существует также класс System.Timers, добавленный на ранних этапах разработки .NET Framework. Однако обычно рекомендуется вместо этого использовать класс System.Threading.Timer, так как в любом случае это всего лишь оболочка для System.Threading.Timer.
Также рекомендуется всегда использовать статический (совместно используемый в VB.NET) System.Threading.Timer, если вы разрабатываете службу Windows и вам требуется периодически запускать таймер. Это позволит избежать преждевременной сборки мусора вашего объекта таймера.
Вот пример таймера в консольном приложении:
Из книги CLR Via C # Джеффа Рихтера. Кстати, эта книга описывает обоснование трех типов таймеров в главе 23, настоятельно рекомендуется.
Вот код для создания простого таймера на одну секунду:
А вот и результат:
РЕДАКТИРОВАТЬ . Не рекомендуется добавлять в код циклы жесткого вращения, поскольку они потребляют циклы ЦП без какой-либо выгоды. В этом случае этот цикл был добавлен только для того, чтобы остановить закрытие приложения, позволяя наблюдать за действиями потока. Но для правильности и уменьшения загрузки процессора в этот цикл был добавлен простой вызов Sleep.
только это-как вы добавляете таймер в консольное приложение C#? Было бы здорово, если бы вы могли предоставить некоторые примеры кода.
7 ответов:
это очень хорошо, однако для того, чтобы имитировать некоторое время прохождения нам нужно запустить команду, которая занимает некоторое время, и это очень ясно во втором примере.
однако стиль использования цикла for для выполнения некоторых функций навсегда занимает много ресурсов устройства, и вместо этого мы можем использовать сборщик мусора, чтобы сделать что-то подобное.
мы можем увидеть эту модификацию в коде из той же книги CLR через C# Third Ed.
использовать систему.Нарезка резьбы.класс Timer.
вот код для создания простого секундного таймера:
и вот результат:
EDIT: это никогда не хорошая идея, чтобы добавить жесткие спиновые петли в код, как они потребляют циклы процессора без выгоды. В этом случае этот цикл был добавлен только для того, чтобы остановить закрытие приложения, позволяя наблюдать за действиями потока. Но ради корректности и для уменьшения использования процессора был добавлен простой вызов сна эта петля.
давайте немного весело!—2—>
или с помощью Rx, короткий и сладкий:
вы также можете использовать свои собственные механизмы синхронизации, если вы хотите немного больше контроля, но меньше точности и больше кода/сложности, но я все равно рекомендую таймер. Используйте это, хотя, если вам нужно иметь контроль над фактическим потоком синхронизации:
будет ваш временной поток (измените это, чтобы остановить, когда reqiuired, и в любой интервал времени вы хотите).
и для использования / запуска вы можете сделать:
обратный вызов-это ваш void parameterless метод, который вы хотите вызвать в каждом интервале. Например:
вы также можете создать свой собственный (если недовольны доступные варианты).
создание собственного Timer реализация довольно простой вещи.
это пример для приложения, которому необходим доступ к COM-объекту в том же потоке, что и остальная часть моей кодовой базы.
вы можете добавить события следующим образом:
чтобы убедиться, что таймер работает, вы должны создать бесконечный цикл следующим образом: