manish_rcc Ответов: 2

Высокая загрузка процессора службы C# windows


Я создал службу windows, запустив эту службу с высокой загрузкой процессора..
Пожалуйста, найдите приведенный ниже код..
здесь метод ComputeData () вызывает процедуру, и эта процедура занимает 1:23 минуты для выполнения. установите здесь 5-минутный интервал для выполнения метода ComputeData ().

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using System.Configuration;

namespace UpdateData
{
   public partial class Service1 : ServiceBase
   {
      static Timer timer;
      public Service1()
      {
         InitializeComponent();
      }
      private static void start_timer()
      {
         timer.Start();
      }
      protected override void OnStart(string[] args)
      {
         timer = new Timer();          
         timer.Interval = TimeSpan.FromMinutes(5).TotalMilliseconds;            
         timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
         timer.Enabled = true;
         timer.Start();
      }

      public static bool ExecuteTime()
      {
         TimeSpan StartingTime = new TimeSpan(
            Int32.Parse(ConfigurationManager.AppSettings["StartingTimeHour"]),
            Int32.Parse(ConfigurationManager.AppSettings["StartingTimeMinute"]), 0);
         TimeSpan EndingTime = new TimeSpan(
            Int32.Parse(ConfigurationManager.AppSettings["EndingTimeHour"]),
            Int32.Parse(ConfigurationManager.AppSettings["EndingTimeMinute"]), 0);

         TimeSpan CurrentTime = DateTime.Now.TimeOfDay;
         return ((CurrentTime > StartingTime) && (CurrentTime < EndingTime));
      }

      static void timer_Elapsed(object sender, ElapsedEventArgs e)
      {
         try
         {
            DateTime TodayDate = DateTime.Now;
            if (TodayDate.DayOfWeek == DayOfWeek.Saturday || TodayDate.DayOfWeek == DayOfWeek.Sunday)
            { }
            else
            {
               while (ExecuteTime())
               {
                  BasicBO.ComputeData();
               }
            }
         }
         catch (Exception ex)
         {
            string msg = ex.Message + " at " + DateTime.Now + " From timer_Elapsed method";
            BasicBO.writeLog(msg, "UpdateVMErrorLog.txt");
         }
      }

      protected override void OnStop()
      {
         string msg = "Service Stoped at : " + DateTime.Now;
         BasicBO.writeLog(msg, "UpdateVMStopLog.txt");
      }
   }
}


Что я уже пробовал:

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

F-ES Sitecore

Возможно, вам лучше установить таймер так, чтобы он срабатывал каждую секунду, а затем в этом случае проверить один раз, должен ли код запускаться, то есть изменить "while" на "if". Как бы то ни было, Ваш код срабатывает мало, но когда он срабатывает, то работает очень долго. Вам лучше заставить его стрелять чаще и бегать меньше времени.

Проблема, с которой вы столкнетесь с этим методом, заключается в том, что вам понадобится какой-то способ запомнить, что ComputeData была запущена в течение этого интервала времени, поскольку таймер, вероятно, будет срабатывать несколько раз в окне, в котором вы хотите запустить код.

Philippe Mori

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

2 Ответов

Рейтинг:
7

johannesnestler

Привет manish_rcc

пожалуйста, взгляните на измененный код и комментарии:

public partial class Service1 : ServiceBase
   {
// 1. Timer not static - one instance per Service...
      Timer timer;

// Configuration can be cached
      TimeSpan startingTime;
      TimeSpan endingTime;

      public Service1()
      {
         InitializeComponent();
      }
      private static void start_timer()
      {
         timer.Start();
      }
      protected override void OnStart(string[] args)
      {
         timer = new Timer();          
// hardcoded interval?
         timer.Interval = TimeSpan.FromMinutes(5).TotalMilliseconds;            
         timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
// no need to call Enable and Start - just Start
         timer.Enabled = true;
         timer.Start();

// Read Configuration only once to cache
         startingTime = new TimeSpan(
            Int32.Parse(ConfigurationManager.AppSettings["StartingTimeHour"]),
            Int32.Parse(ConfigurationManager.AppSettings["StartingTimeMinute"]), 0);
         endingTime = new TimeSpan(
            Int32.Parse(ConfigurationManager.AppSettings["EndingTimeHour"]),
            Int32.Parse(ConfigurationManager.AppSettings["EndingTimeMinute"]), 0);

      }
 
// Better naming: Functions returning booleans should be named with Is/Has/Can...
      public static bool ShouldExecute()
      { 
         TimeSpan CurrentTime = DateTime.Now.TimeOfDay;
         return ((CurrentTime > startingTime) && (CurrentTime < endingTime));
      }
 
      static void timer_Elapsed(object sender, ElapsedEventArgs e)
      {
         try
         {
            DateTime TodayDate = DateTime.Now;
            if (TodayDate.DayOfWeek == DayOfWeek.Saturday || TodayDate.DayOfWeek == DayOfWeek.Sunday)
            {
// Exit early, no need to do the check on weekends (hardcoded values a good idea?)
                return;
            }
            else
            {
// no while here, you are already in a timer(-loop) - just check if operation should run now, timer will come here after 5 minutes (the intervall you specified to the timer, again hardcoded value a good idea?)
               if(ShouldExecute())
               {
                  BasicBO.ComputeData();
               }
            }
         }
         catch (Exception ex)
         {
            string msg = ex.Message + " at " + DateTime.Now + " From timer_Elapsed method";
            BasicBO.writeLog(msg, "UpdateVMErrorLog.txt");
         }
      }
 
      protected override void OnStop()
      {
         string msg = "Service Stoped at : " + DateTime.Now;
         BasicBO.writeLog(msg, "UpdateVMStopLog.txt");
      }
   }


Видите ли, вас смущает то, что таймер уже представляет собой своего рода "петлю" для проверки...

С уважением
Иоганнес


Midi_Mick

Я тоже собиралась пойти туда ради него - как только моя голова достаточно прояснится. Молодец, приятель. +5

manish_rcc

Большое спасибо за помощь.

johannesnestler

добро пожаловать - теперь все ясно и работает? (Я изменил ваш код из моей головы в блокноте...), не стесняйтесь задавать дальнейшие вопросы...

manish_rcc

Да, Большое Спасибо ..Код теперь работает отлично.

Рейтинг:
20

Midi_Mick

Линии, которые будут жевать ваш процессор, это

while (ExecuteTime())
{
BasicBO.ComputeData();
}


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

Или это, или, может быть, вы имели в виду if скорее, чем while там.


johannesnestler

именно это я и заметил

manish_rcc

Спасибо за повтор.

похоже, что приведенный ниже код работает на меня.

пока (ExecuteTime())
{
Бейсикбо.ComputeData();
Нить.Сон(5 * 60 * 1000);//нить сна через каждые 5 минут
}

johannesnestler

О нет, мужчина , пожалуйста, посмотрите на мое решение...