Служба Windows с таймером

25

Я создал службу windows с таймером в С#.net. он отлично работает, когда я отлаживаю/создаю проект в visual studio, но он не выполняет его работу после установки.

Что может быть причиной этого?

код:

public partial class Service1 : ServiceBase
{
        FileStream fs;
        StreamWriter m_streamWriter;
        Timer tm = new Timer();

        public Service1()
        {
            InitializeComponent();

            this.ServiceName = "timerservice";

            tm.Interval = 2000;
            tm.Tick += new EventHandler(PerformOperations);
            tm.Start();

            fs = new FileStream(@"c:\mcWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write);

            m_streamWriter = new StreamWriter(fs);
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
        }

        private void PerformOperations(object sener, EventArgs e)
        {
            //StreamWriter swr = new StreamWriter("c:\\test_from_database.txt",true);

            try
            {
                OdbcConnection con = new OdbcConnection("DSN=liquor_data");

                OdbcDataAdapter adp = new OdbcDataAdapter("", con);

                DataSet ds = new DataSet();

                string sql = "select * from item_group";
                adp.SelectCommand.CommandText = sql;

                adp.Fill(ds, "item_group");

                foreach (DataRow dr in ds.Tables["item_group"].Rows)
                {
                    //      swr.Write(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");

                    //Console.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
                    m_streamWriter.WriteLine(dr["group_name"].ToString() + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n");
                }

                m_streamWriter.Flush();
            }

            catch (Exception ex)
            {
                // swr.Write("Error :"+ ex.Message + "\t\t" + DateTime.Now.TimeOfDay.ToString() + "\n"); }
            }
        }
    }
  • 0
    У учетной записи есть разрешение на запуск службы Windows после установки?
  • 0
    да .. это админ ..
Показать ещё 3 комментария
Теги:
timer
windows-services

3 ответа

50
Лучший ответ

Первый подход с Windows Service нелегкий.

Давным-давно я написал службу С#.

Это логика класса Service (проверена, отлично работает):

namespace MyServiceApp
{
    public class MyService : ServiceBase
    {
        private System.Timers.Timer timer;

        protected override void OnStart(string[] args)
        {
            this.timer = new System.Timers.Timer(30000D);  // 30000 milliseconds = 30 seconds
            this.timer.AutoReset = true;
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
            this.timer.Start();
        }

        protected override void OnStop()
        {
            this.timer.Stop();
            this.timer = null;
        }

        private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            MyServiceApp.ServiceWork.Main(); // my separate static method for do work
        }

        public MyService()
        {
            this.ServiceName = "MyService";
        }

        // service entry point
        static void Main()
        {
            System.ServiceProcess.ServiceBase.Run(new MyService());
        }
    }
}

Я рекомендую вам написать свою реальную работу службы в отдельном статическом методе (почему бы и нет, в консольном приложении... просто добавить ссылку на него), чтобы упростить отладку и очистить код службы.

Убедитесь, что интервал достаточен и запись в журнале ТОЛЬКО в OnStart и OnStop отменяет.

Надеюсь, это поможет!

  • 0
    msgstr "и писать в журнале ТОЛЬКО в переопределениях OnStart и OnStop." Зачем? Разве вы не можете записывать в текстовый файл при каждом прошедшем таймере? У меня эта проблема ... У меня есть своя собственная функция, которая пишет в текстовый файл (журнал), но она не работает (просто работает при запуске и остановке), вы можете помочь мне понять, в чем проблема?
  • 0
    Да, вы также можете записать в метод timer_tick, но для меня это не нужно (основной метод работы должен записывать свой журнал). Можете ли вы показать мне больше (исключение и т. Д.)?
7

Вам нужно поместить свой основной код в метод OnStart.

Этот другой мой ответ мог бы помочь.

Вам нужно будет поместить некоторый код для включения отладки в visual-studio, сохраняя при этом ваше приложение действительным в качестве службы Windows. Этот другой поток SO охватывает проблему отладки Windows-сервиса.

ИЗМЕНИТЬ

См. также документацию здесь для метода OnStart в MSDN, где вы можете прочитать это:

Не используйте конструктор для выполнения обработки, которая должна быть в OnStart. Используйте OnStart для обработки всей инициализации вашего сервиса. конструктор вызывается, когда запускается исполняемый файл приложения, а не когда служба запускается. Исполняемый файл работает до OnStart. Когда ты продолжить, например, конструктор не вызывается снова, потому что SCM уже содержит объект в памяти. Если OnStop освобождает ресурсы выделяется в конструкторе, а не в OnStart, необходимо ресурсы не будут создаваться снова во второй раз, когда служба называется.

0

Здесь приведен рабочий пример, в котором запуск службы запускается в OnTimedEvent таймера, который реализован как делегат в классе ServiceBase, а логика таймера инкапсулируется в методе SetupProcessingTimer():

public partial class MyServiceProject: ServiceBase
{

private Timer _timer;

public MyServiceProject()
{
    InitializeComponent();
}

private void SetupProcessingTimer()
{
    _timer = new Timer();
    _timer.AutoReset = true;
    double interval = Settings.Default.Interval;
    _timer.Interval = interval * 60000;
    _timer.Enabled = true;
    _timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // begin your service work
    MakeSomething();
}

protected override void OnStart(string[] args)
{
    SetupProcessingTimer();
}

...
}

Интервал определяется в app.config в минутах:

<userSettings>
    <MyProject.Properties.Settings>
        <setting name="Interval" serializeAs="String">
            <value>1</value>
        </setting>
    </MyProject.Properties.Settings>
</userSettings>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню