2012-10-14 48 views
27

我用c#.net中的定時器創建了一個windows服務。它工作正常,而我在Visual Studio中調試/建立項目,但它不會在安裝後執行它的操作。帶定時器的Windows服務

這背後的原因是什麼?

代碼:

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服務的權限? – urlreader

+0

yes..its admin .. –

+0

嘗試取消註釋以查看是否有錯誤正在丟失。同時檢查窗口事件日誌是否有任何錯誤。 – MattW

回答

50

與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覆蓋中記錄日誌。

希望這會有所幫助!

+0

「,並且僅在OnStart和OnStop覆蓋中寫入日誌。」爲什麼?你不能在每個定時器事件發生時寫入一個文本文件嗎?我有這個問題...我有我自己的函數寫入文本文件(日誌),但它不工作(只在開始和停止工作),你能幫我理解有什麼問題嗎? –

+0

是的,你也可以寫入timer_tick方法,但對我來說是不必要的(主要的工作方法必須寫入它的日誌)。你能告訴我更多(例外等)嗎? –

7

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

這個我的其他SO answer可能會有所幫助。

您將需要放置一些代碼來在visual-studio中啓用調試,同時保持您的應用程序作爲Windows服務有效。其他SO thread涵蓋了調試Windows服務的問題。

編輯

還請查看可用的文檔hereOnStart方法在MSDN,人們可以這樣說的:

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

0

下面是在其中服務的執行在其被實現爲在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>