Windows服务与计时器(Windows service with timer)

2019-06-18 12:51发布

我创建了一个窗口服务,在C#.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"); }
            }
        }
    }

Answer 1:

与Windows服务至上的做法是不容易..

很久以前,我写了一个C#的服务。

这是服务类的逻辑(测试时,正常工作):

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重写编写。

希望这可以帮助!



Answer 2:

你需要把你的主代码上OnStart方法。

这其他的SO回答我的可能的帮助。

你需要把一些代码,以视觉工作室中启用调试,同时保持你的应用程序是一个有效的窗口服务。 这其他SO线程覆盖调试窗口服务的问题。

编辑

另请参阅提供的文档这里的OnStart在MSDN方法,人们可以这样说的:

不要使用构造函数进行处理,应在OnStart中 。 使用的OnStart处理服务的所有初始化。 应用程序的可执行文件运行,而不是服务运行时,当构造函数被调用。 可执行的OnStart之前运行。 当你继续,例如,构造函数不再调用,因为SCM已经持有该对象在内存中。 如果调用OnStop释放在构造函数中,而不是在OnStart中分配的资源,所需要的资源,不会再次创造了第二次服务调用。



Answer 3:

下面是在该服务的执行,其中在ServiceBase类实现为代理和定时器逻辑被封装在称为SetupProcessingTimer()方法中的定时器的OnTimedEvent开始工作示例:

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>


文章来源: Windows service with timer