Windows service with timer

我的未来我决定 提交于 2019-12-17 04:29:14

问题


I have created a windows service with timer in c#.net. it works fine while i debug/build the project in visual studio but it does not perform its operation after installation.

What might be the reason behind this ?

code :

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"); }
            }
        }
    }

回答1:


First approach with Windows Service is not easy..

A long time ago, I wrote a C# service.

This is the logic of the Service class (tested, works fine):

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());
        }
    }
}

I recommend you write your real service work in a separate static method (why not, in a console application...just add reference to it), to simplify debugging and clean service code.

Make sure the interval is enough, and write in log ONLY in OnStart and OnStop overrides.

Hope this helps!




回答2:


You need to put your main code on the OnStart method.

This other SO answer of mine might help.

You will need to put some code to enable debugging within visual-studio while maintaining your application valid as a windows-service. This other SO thread cover the issue of debugging a windows-service.

EDIT:

Please see also the documentation available here for the OnStart method at the MSDN where one can read this:

Do not use the constructor to perform processing that should be in OnStart. Use OnStart to handle all initialization of your service. The constructor is called when the application's executable runs, not when the service runs. The executable runs before OnStart. When you continue, for example, the constructor is not called again because the SCM already holds the object in memory. If OnStop releases resources allocated in the constructor rather than in OnStart, the needed resources would not be created again the second time the service is called.




回答3:


Here's a working example in which the execution of the service is started in the OnTimedEvent of the Timer which is implemented as delegate in the ServiceBase class and the Timer logic is encapsulated in a method called 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();
}

...
}

The Interval is defined in app.config in minutes:

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


来源:https://stackoverflow.com/questions/12885013/windows-service-with-timer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!