Почему служба Windows с Timer отрабатывает только один раз?
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; using TankService.Models; using System.Web; using Newtonsoft.Json; namespace TankService { public partial class Service1 : ServiceBase { protected override async void OnStart(string[] args) { //************************************ TimerCallback timeCB = new TimerCallback(Count); Timer time = new Timer(timeCB, null, 0, 60000); //************************************ } public static asopnEntities db1 = new asopnEntities(); public static ChemLabEntities db2 = new ChemLabEntities(); public class TankInventt { public DateTime Data { get; set; } public int Filial { get; set; } } //-------------------------------------------------------------- public class tankRadar { } public class tankRadarObert { public List<tankRadar> ReadResults { get; set; } } //Создадим класс для заполнения данных уровней и темпреатур резервуаров public class tankdatas { } public class CalculatorData { /// <summary> /// Oil density at a temperature of 15 °C. /// </summary> public double Dens15 { get; set; } public double DensTP { get; set; } } public class Density636 : ICloneable { public Density636() { } public object Clone() { return new Density636 { }; } } public class Asopn { public static List<LastTanksResultMoz> LM = new List<LastTanksResultMoz>(); //список записей из представления химанализа по Мозырю public static List<LastTanksResultPol> LP = new List<LastTanksResultPol>(); //список записей из представления по Полоцку public static List<LastMechanResultMoz> LMM = new List<LastMechanResultMoz>(); //список записей механических примесей в резервуарах ЛПДС Мозырь public class Person { public string name { get; set; } public int age { get; set; } } public async static Task<List<TankInventt>> Spis() { List<TagCorrespondence> tagcorrespond = new List<TagCorrespondence>(); tagcorrespond = db1.TagCorrespondence.Where(tu => tu.FilialID == 1 && tu.Enable == 1).ToList(); List<string> listdata = new List<string>(); foreach (var item in tagcorrespond) { listdata.Add(item.lev); listdata.Add(item.temp); } List<string> listdataPolock = new List<string>(); foreach (var item in tagcorrespondPolock) { listdataPolock.Add(item.lev); listdataPolock.Add(item.temp); } //Заполним список данными уровней и температур List<tankdatas> listtankdatas = new List<tankdatas>(); foreach (var ty in tagcorrespond) { listtankdatas.Add(tankdatasITEM); } foreach (var tPol in tagcorrespondPolock) { listtankdatas.Add(tankdatasITEM); } LP = db2.LastTanksResultPol.ToList(); LM = db2.LastTanksResultMoz.ToList(); LMM = db2.LastMechanResultMoz.ToList(); ListLastInv = db1.DonnyOstat.ToList(); TankI.Clear(); foreach (var item in listtankdatas) { string dt = Convert.ToString(item.Dat).Substring(0, 14) + "00:00.000"; DateTime dtTime = Convert.ToDateTime(dt); TankI.Add(new TankInventt() { Data = dtTime, Filial = item.FilialID, Rezer = item.tankid, Urov = Convert.ToInt32(lev), UrovH2O = Convert.ToInt32(UrovH2O), UrovNeft = Convert.ToInt32(UrovNeft), V = V, P = PCalc, Temp = Temp1, MassaBrutto = MassaBrutto, H2O = H2O, Salt = SaltProc, Meh = Meh, BalProc = BalProc, BalTonn = BalTonn, MassaNetto = MassaNetto, Hmin = Hmin, Vmin = MVmin, dMBalmin = MMin, dMNettomin = MNmin, type = type, VH2O = VH2ORasch, VNeft = VNeft }); ; } return TankI; } } public Service1() { InitializeComponent(); } public static async void Count(object obj) { string writePath = "log.txt"; filials hhh = new filials(); tankinfo hj = new tankinfo(); TankInv TankinV = new TankInv(); try { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-----------ИНВЕНТАРИЗАЦИЯ НА " + DateTime.Now.ToString() + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-----------------------------------------------------------------n"); foreach (var item in await Asopn.Spis()) { //---Запись таблицы в БД--------------------------------------------------------------------- TankinV.Data = item.Data; TankinV.Filial = item.Filial; TankinV.Rezer = item.Rezer; TankinV.Urov = item.Urov; TankinV.UrovH2O = item.UrovH2O; TankinV.UrovNeft = item.UrovNeft; TankinV.V = Convert.ToDecimal(Math.Round(item.V, 3)); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", item.Data + " | " + item.Filial + " | " + item.Rezer + " | " + item.Urov + " | " + item.UrovH2O + " | " + item.UrovNeft + " | " + item.V + " | " + item.Temp + " | " + item.P + " | " + item.MassaBrutto + " | " + item.H2O + " | " + item.Salt + " | " + "n"); } File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Запись инвентаризации успешно добавлена в БД " + DateTime.Now + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-----------------------------------------------------------------n"); } catch (Exception ex) { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Ошибка записи! Код ошибки: " + ex.ToString() + "n"); } List<TankInv> TableInv = new List<TankInv>(); TableInv = db1.TankInv.OrderByDescending(o => o.Data).ToList(); DateTime LastDate = TableInv.FirstOrDefault().Data; if (LastDate.ToShortDateString() == "00:00") { try { { SvodkaSutki SutSv = new SvodkaSutki(); var TabInv = TableInv.Where(y => y.Data == LastDate).GroupBy(k => k.Filial); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "СУТОЧНАЯ СВОДКА НА " + DateTime.Now.ToString() + "n"); foreach (var t in TabInv) { int kol = 0; foreach (var i in t) { } db1.SvodkaSutki.Add(SutSv); db1.SaveChanges(); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", t.Key + " | " + LastDate + " | " + VNeftItog + " | " + MassaBalItog + " | " + MassaNettoItog + " | " + MassaBruttoOstat + " | " + MassaBruttoOstat + " | " + MassaNettoMinItog + " | " + (MassaNettoItog - MassaNettoMinItog) + " | " + "n"); } File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Данные суточной сводки записаны " + DateTime.Now + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "----------------------------------------------------n"); } } catch (Exception ex) { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Ошибка записи! Код ошибки: " + ex.ToString() + "n"); } } else { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Время не равно 00:00!!! Запись в БД не производится!!!n"); } } protected override void OnStop() { } } } |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; using TankService.Models; using System.Web; using Newtonsoft.Json; namespace TankService { public partial class Service1 : ServiceBase { protected override async void OnStart(string[] args) { //************************************ TimerCallback timeCB = new TimerCallback(Count); Timer time = new Timer(timeCB, null, 0, 60000); //************************************ } public static asopnEntities db1 = new asopnEntities(); public static ChemLabEntities db2 = new ChemLabEntities(); public class TankInventt { public DateTime Data { get; set; } public int Filial { get; set; } } //-------------------------------------------------------------- public class tankRadar { } public class tankRadarObert { public List<tankRadar> ReadResults { get; set; } } //Создадим класс для заполнения данных уровней и темпреатур резервуаров public class tankdatas { } public class CalculatorData { /// <summary> /// Oil density at a temperature of 15 °C. /// </summary> public double Dens15 { get; set; } public double DensTP { get; set; } } public class Density636 : ICloneable { public Density636() { } public object Clone() { return new Density636 { }; } } public class Asopn { public static List<LastTanksResultMoz> LM = new List<LastTanksResultMoz>(); //список записей из представления химанализа по Мозырю public static List<LastTanksResultPol> LP = new List<LastTanksResultPol>(); //список записей из представления по Полоцку public static List<LastMechanResultMoz> LMM = new List<LastMechanResultMoz>(); //список записей механических примесей в резервуарах ЛПДС Мозырь public class Person { public string name { get; set; } public int age { get; set; } } public async static Task<List<TankInventt>> Spis() { List<TagCorrespondence> tagcorrespond = new List<TagCorrespondence>(); tagcorrespond = db1.TagCorrespondence.Where(tu => tu.FilialID == 1 && tu.Enable == 1).ToList(); List<string> listdata = new List<string>(); foreach (var item in tagcorrespond) { listdata.Add(item.lev); listdata.Add(item.temp); } List<string> listdataPolock = new List<string>(); foreach (var item in tagcorrespondPolock) { listdataPolock.Add(item.lev); listdataPolock.Add(item.temp); } //Заполним список данными уровней и температур List<tankdatas> listtankdatas = new List<tankdatas>(); foreach (var ty in tagcorrespond) { listtankdatas.Add(tankdatasITEM); } foreach (var tPol in tagcorrespondPolock) { listtankdatas.Add(tankdatasITEM); } LP = db2.LastTanksResultPol.ToList(); LM = db2.LastTanksResultMoz.ToList(); LMM = db2.LastMechanResultMoz.ToList(); ListLastInv = db1.DonnyOstat.ToList(); TankI.Clear(); foreach (var item in listtankdatas) { string dt = Convert.ToString(item.Dat).Substring(0, 14) + "00:00.000"; DateTime dtTime = Convert.ToDateTime(dt); TankI.Add(new TankInventt() { Data = dtTime, Filial = item.FilialID, Rezer = item.tankid, Urov = Convert.ToInt32(lev), UrovH2O = Convert.ToInt32(UrovH2O), UrovNeft = Convert.ToInt32(UrovNeft), V = V, P = PCalc, Temp = Temp1, MassaBrutto = MassaBrutto, H2O = H2O, Salt = SaltProc, Meh = Meh, BalProc = BalProc, BalTonn = BalTonn, MassaNetto = MassaNetto, Hmin = Hmin, Vmin = MVmin, dMBalmin = MMin, dMNettomin = MNmin, type = type, VH2O = VH2ORasch, VNeft = VNeft }); ; } return TankI; } } public Service1() { InitializeComponent(); } public static async void Count(object obj) { string writePath = "log.txt"; filials hhh = new filials(); tankinfo hj = new tankinfo(); TankInv TankinV = new TankInv(); try { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-----------ИНВЕНТАРИЗАЦИЯ НА " + DateTime.Now.ToString() + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-----------------------------------------------------------------n"); foreach (var item in await Asopn.Spis()) { //---Запись таблицы в БД--------------------------------------------------------------------- TankinV.Data = item.Data; TankinV.Filial = item.Filial; TankinV.Rezer = item.Rezer; TankinV.Urov = item.Urov; TankinV.UrovH2O = item.UrovH2O; TankinV.UrovNeft = item.UrovNeft; TankinV.V = Convert.ToDecimal(Math.Round(item.V, 3)); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", item.Data + " | " + item.Filial + " | " + item.Rezer + " | " + item.Urov + " | " + item.UrovH2O + " | " + item.UrovNeft + " | " + item.V + " | " + item.Temp + " | " + item.P + " | " + item.MassaBrutto + " | " + item.H2O + " | " + item.Salt + " | " + "n"); } File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Запись инвентаризации успешно добавлена в БД " + DateTime.Now + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-----------------------------------------------------------------n"); } catch (Exception ex) { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Ошибка записи! Код ошибки: " + ex.ToString() + "n"); } List<TankInv> TableInv = new List<TankInv>(); TableInv = db1.TankInv.OrderByDescending(o => o.Data).ToList(); DateTime LastDate = TableInv.FirstOrDefault().Data; if (LastDate.ToShortDateString() == "00:00") { try { { SvodkaSutki SutSv = new SvodkaSutki(); var TabInv = TableInv.Where(y => y.Data == LastDate).GroupBy(k => k.Filial); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "СУТОЧНАЯ СВОДКА НА " + DateTime.Now.ToString() + "n"); foreach (var t in TabInv) { int kol = 0; foreach (var i in t) { } db1.SvodkaSutki.Add(SutSv); db1.SaveChanges(); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", t.Key + " | " + LastDate + " | " + VNeftItog + " | " + MassaBalItog + " | " + MassaNettoItog + " | " + MassaBruttoOstat + " | " + MassaBruttoOstat + " | " + MassaNettoMinItog + " | " + (MassaNettoItog - MassaNettoMinItog) + " | " + "n"); } File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Данные суточной сводки записаны " + DateTime.Now + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "----------------------------------------------------n"); } } catch (Exception ex) { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Ошибка записи! Код ошибки: " + ex.ToString() + "n"); } } else { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Время не равно 00:00!!! Запись в БД не производится!!!n"); } } protected override void OnStop() { } } }
Дополнительно:
а как вы хотели
можно ещё почитать дукоменцатию. осторожно - будет много букв
using System.Timers; using System; Timer1 = new System.Timers.Timer(); Timer1.Elapsed += new ElapsedEventHandler(OnElapsedTimer1); private void OnElapsedTimer1(object source, ElapsedEventArgs args){ CollectMetrics(); } |
using System.Timers; using System; Timer1 = new System.Timers.Timer(); Timer1.Elapsed += new ElapsedEventHandler(OnElapsedTimer1); private void OnElapsedTimer1(object source, ElapsedEventArgs args){ CollectMetrics(); }
если помогло - я положу в ответы вы отметите решением
Я использовал Timer из System.Threading. И таймер запускался только один раз. Хотя когда я делал тестовую службу и через каждые 20с. писал дату в текстовый файл - все работало.
Потом я переделал и использовал Timer из System.Timers. И все заработало.
Скорее всего это связано из-за асинхронных методов, которые я использовал в своем приложении.
Ответы:
Скорее всего проблема с GC.
Ты создаешь локальную переменную таймера и никуда не сохраняешь. В результате, по окончании OnStart на эту переменную никто не указывает и в результате ее собирает GC. Дополнительно метод Count - статический, т.е. ссылки на текущий объект Service1 тоже не сохраняется.
Попробуй 2 вещи:
- Сделать Count не статическим (но след. вариант лучше)
- Хранить этот таймер в поле (инициализируешь в OnStart). Дополнительно в этой случае стоит останавливать этот таймер в OnStop
- Вот такой код работает. Таймер срабатывает и данные записываются.
Почему предыдущий код так не работает? Таймер описан такжеusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTest { public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { TimerCallback timeCB = new TimerCallback(TimerCallback); Timer time = new Timer(timeCB, null, 0, 20000); } static void TimerCallback(object state) { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Текущее время: "+ DateTime.Now.ToString() + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-n"); } protected override void OnStop() { } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.IO; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MyTest { public partial class Service1 : ServiceBase { public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { TimerCallback timeCB = new TimerCallback(TimerCallback); Timer time = new Timer(timeCB, null, 0, 20000); } static void TimerCallback(object state) { File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "Текущее время: "+ DateTime.Now.ToString() + "n"); File.AppendAllText(@"C:/Users/sov/Downloads/Test.txt", "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-n"); } protected override void OnStop() { } } }
- $kyD@rk, возможно происходит исключение и работа просто прекращается. просто так я сказать не могу - никаких вводных данных для понимания у меня нет (ни логов, ни кейсов, ничего)
Простите, у вас проблемы с установкой Visual Studio? Или у вас компилятор сломался, что вы не можете запустить код?
- VS у меня установлена. И компилятор работает. Приложение создано как служба, как его запустить? Могу только как службу собрать. Сделал такое же только консольное приложение - все работает.
- $kyD@rk, ну собирайте как можете) Зачем нам весь код этот? Я его должен запускать или что? Где ошибка? Какая ошибка? Почему возникает? Я это должен сейчас всё взять, запустить и играться с вашей программой, потому что вам лень описать вашу проблему?
- Ошибки нет. Служба запускается и отрабатывает, но только один раз. В методе OnStart есть таймер, который должен запускать колбек каждую минуту, но его не запускает. Вот я и задал вопрос - почему запускается только один раз? Может таймер нужно не в OnStart прописывать? Может еще что-то? Может кто-нибудь сталкивался с похожей проблемой. Я совсем не просил чтобы кто-то запускал и игрался с моим кодом.
- $kyD@rk, а вероятно придется
- Nik Faraday, ну не знаю... если вопрос цепляет - я хочу КОД ... и дебажить в студии
- Nik Faraday, считаешь это плохо? я маньяк?
- $kyD@rk, https://learn.microsoft.com/en-us/dotnet/framework...
дебажте ручками, вот и все.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Служба Windows с таймером может работать только один раз из-за неправильной реализации кода или неправильных настроек службы. Вот несколько возможных причин, почему ваша служба Windows с таймером может отрабатывать только один раз:
1. Неправильная инициализация таймера: Убедитесь, что вы правильно инициализируете таймер в коде службы. Убедитесь, что установили интервал таймера и обработчик событий таймера.
2. Ошибка в обработчике событий таймера: Проверьте ваш обработчик событий таймера на наличие ошибок. Убедитесь, что код в обработчике событий таймера выполняется правильно и не приводит к завершению работы службы.
3. Неправильные настройки службы: Проверьте настройки вашей службы Windows. Убедитесь, что служба настроена для повторного запуска таймера после каждого срабатывания.
4. Проблемы с окружением: Проверьте, что ваша служба Windows запускается в правильном окружении. Убедитесь, что нет конфликтов с другими службами или процессами, которые могут препятствовать работе вашей службы с таймером.
Прежде чем искать причину проблемы, рекомендуется добавить логирование в ваш код, чтобы отслеживать работу таймера и обнаруживать возможные ошибки. Также рекомендуется провести отладку вашего кода, чтобы выявить возможные ошибки и улучшить производительность вашей службы с таймером.
Возможно, после тщательного анализа вашего кода и настроек службы Windows, вы сможете исправить проблему с тем, что служба с таймером отрабатывает только один раз.