2013-12-16 64 views
0

我有我的服務器做了一個窗口服務...未能保持Windows服務與計時器活着

我需要檢查每分鐘,如果在我的SQL數據庫中的一些新的信息。

因此,我做了一個Windows服務,創建一個間隔1分鐘的計時器。 但Windows服務設置計時器並結束運行。

它是這樣的:

    • 啓動服務
    • 與間隔
    • 整理並退出設置定時器荷蘭國際集團服務< - 我想保持它活着

正如你所看到的服務出口,我想在Windows服務不停止運行每分鐘....

我可以看到在事件查看器那裏有「服務啓動成功」。並且「服務已成功停止」。

我該怎麼辦?

P.S:我以爲Timer應該與out exit一起工作......或者我錯了嗎?

CODE:

Windows服務:

static void Main(string[] args) 
     { 
      try 
      { 
       Utils.SetConfigFile(); 
       var ServiceToRun = new TaoTimer(); 
       ServiceToRun.Start(); 
      } 
      catch (Exception ex) 
      { 
       EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error); 
      } 
     } 

TaoTimer:

public partial class TaoTimer : ServiceBase 
{ 
    List<TimerModel> timerList; 
    public TaoTimer() 
    { 
     InitializeComponent(); 
    } 
    protected override void OnStart(string[] args) 
    { 
     EventLog.WriteEntry("Started"); 
    } 
    public void SetTimer(TimerModel timerModel) 
    { 
     int minute = 1000 * 60; 
     try 
     { 
      AlertTimer at = new AlertTimer(timerModel, minute); 
      at.Start(); 
     } 
     catch 
     { 

     } 
    } 
    protected override void OnStop() 
    { 
     EventLog.WriteEntry("Stopped"); 
    } 
    protected override void OnPause() 
    { 
     EventLog.WriteEntry("Paused"); 
    } 
    protected override void OnContinue() 
    { 
     EventLog.WriteEntry("Continuing"); 
    } 
    protected override void OnShutdown() 
    { 
     EventLog.WriteEntry("ShutDowned"); 
    } 
    public void Start() 
    { 
     SetTimerList(); 
    } 
    protected void SetTimerList()//Read Config from xml and start the timer 
    { 
     XElement root = XElement.Load(@"C:\TaoTimer\Data.xml"); 
     timerList = new List<TimerModel>(from d in root.Descendants("Timer") 
             select new TimerModel(
          d.Element("Id").Value.ToString(), 
          d.Element("Name").Value.ToString(), 
          d.Element("InterVal").Value.ToString(), 
          d.Element("TimeFormat").Value.ToString(), 
          d.Element("Day").Value.ToString(), 
          d.Element("TimeStamp").Value.ToString())); 
     timerList.ForEach(i => SetTimer(i)); 
    } 
} 

AlertTimer:

public class AlertTimer 
{ 
    static System.Timers.Timer aTimer = new System.Timers.Timer(); 
    public AlertTimer(TimerModel timerModel, int milliseconds) 
    { 
     aTimer.Elapsed += new ElapsedEventHandler((sender, e) => OnTimedEvent(sender, e, timerModel)); 
     aTimer.Interval = milliseconds; 
    }  
    public void Start() 
    { 
     aTimer.Enabled = true; 
    } 
    public static void OnTimedEvent(object source, ElapsedEventArgs e, TimerModel timerModel) 
    { 
     getAbsenceContacts.Start();<-- NEVER GETS HERE.... 
    } 
} 
+0

檢查Windows事件日誌中的未處理異常,使其無法運行。 –

+0

@MichaelPerrenoud已經完成了......沒有未處理的異常... – Ofear

+0

你是否已經獲得'Started'事件日誌? –

回答

1

你並不真正開始你的服務。你正在調用一個名爲Start的方法,它不是Windows服務類層次結構的一部分,它只是你定義的一個方法。你的方法運行並結束,所以服務退出。

試試這個:

static void Main(string[] args) 
    { 
     try 
     { 
      Utils.SetConfigFile(); 
      ServiceBase[] ServicesToRun; 
      ServicesToRun = new ServiceBase[] 
      { 
       new TaoTimer() 
      }; 
      ServiceBase.Run(ServicesToRun); 
     } 
     catch (Exception ex) 
     { 
      EventLog.WriteEntry("Application", ex.ToString(), EventLogEntryType.Error); 
     } 
    } 

public partial class TaoTimer : ServiceBase 
{ 
    ... 
    protected override void OnStart(string[] args) 
    { 
     SetTimerList(); 
     EventLog.WriteEntry("Started"); 
    } 
    .... 
} 

和TaoTimer完全刪除Start方法。

1

您需要將您的AlertTimer實例存儲在某些會延長服務生命週期的內容中(例如,在List<AlertTimer>中聲明爲TaoTimer內的字段。

這只是在Timer的文檔中真正提到的是,計時器本身並不會阻止自己被垃圾收集。這個例子說:

// Normally, the timer is declared at the class level, 
    // so that it stays in scope as long as it is needed. 
    // If the timer is declared in a long-running method, 
    // KeepAlive must be used to prevent the JIT compiler 
    // from allowing aggressive garbage collection to occur 
    // before the method ends. You can experiment with this 
    // by commenting out the class-level declaration and 
    // uncommenting the declaration below; then uncomment 
    // the GC.KeepAlive(aTimer) at the end of the method. 
    //System.Timers.Timer aTimer; 

現在,雖然你的計時器的爲您AlertTimer類的內部類級別聲明,沒有什麼可以阻止AlertTimer情況下,自身做起,從收集。 GC只保留可傳遞到達的事物。一旦AlertTimer實例可收集,您的Timer對象也是可收集的。