簡體   English   中英

Windows服務與計時器

[英]Windows service with timer

我在c#.net中創建了一個帶有計時器的Windows服務。 它在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"); }
            }
        }
    }

使用Windows服務的第一種方法並不容易..

很久以前,我寫了一個C#服務。

這是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覆蓋中寫入日志。

希望這可以幫助!

您需要將主代碼放在OnStart方法上。

我的另一個答案可能有所幫助。

您需要放置一些代碼以在visual-studio中啟用調試,同時保持您的應用程序作為Windows服務有效。 這個其他SO線程涵蓋了調試Windows服務的問題。

編輯

另請參閱提供的文檔這里OnStart在MSDN方法,人們可以這樣說的:

不要使用構造函數來執行應該在OnStart中的處理 使用OnStart處理服務的所有初始化。 構造函數在應用程序的可執行文件運行時調用,而不是在服務運行時調用。 可執行文件在OnStart之前運行。 例如,當您繼續時,不會再次調用構造函數,因為SCM已將對象保存在內存中。 如果OnStop釋放在構造函數而不是OnStart中分配的資源,則第二次調用服務時將不會再次創建所需的資源。

這是一個工作示例,其中服務的執行是在Timer的OnTimedEvent中啟動的,它在ServiceBase類中實現為委托,Timer邏輯封裝在名為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();
}

...
}

Interval在app.config中以分鍾為單位定義:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM