2010-10-08 117 views
1

有人可以讓我知道如何從Windows服務(在C#中)運行長時間運行的進程嗎?該過程可能需要幾小時才能完成。該服務應檢查數據庫中是否有要執行的待執行作業。每項工作可以花費很長時間完成。如果沒有掛起的作業,則應該休眠2分鐘(可配置),然後重新開始。我如何使用Windows服務來做到這一點?提前致謝。如何在Windows服務中運行長時間運行的進程?

回答

1
  1. 創建一個新的「Windows服務」項目。
  2. 重寫OnStart方法來創建一個線程。該線程將處理輪詢和處理。
  3. 重寫OnStop方法以設置標誌。來自步驟2的線程監視這個標誌並相應地終止它自己。
  4. 打開Service類的設計表面。在「屬性」窗口的底部有一個名爲「添加安裝程序」的鏈接。點擊它。
  5. 使用InstallUtil或將其放入安裝程序包中來安裝suervice。

我一直在寫服務,所以隨時問我後續問題。

+0

我其實不喜歡服務選項,因爲它每隔兩分鐘就會一直敲擊數據庫,以檢查是否有任何要執行的任務,並且在沒有任何任務執行時浪費CPU時間。相反,我喜歡事件驅動的模型,只有當有待執行的作業時,進程纔會被喚醒。我認爲MSMQ是可能的,但我不熟悉它,需要了解如何使用它。謝謝回覆。這個過程應該能夠產生多個線程來節省執行多個掛起作業的時間。如果比平時花費的時間更長,還需要殺死該進程 – RKP 2010-10-11 10:49:12

+0

有趣的是,您應該提及MSMQ。當有工作要做時,我確實有SQL Server發送MSMQ消息。然後通過服務觀看隊列。一旦遇到非常罕見的情況,我將失去一條MSMQ消息,但只有在幾秒鐘內發送成千上萬條消息時纔會發生。 – 2010-10-12 18:26:04

0

沒有什麼特殊的技巧吧,除了你不能使用任何GUI /窗體或用戶輸入。根據定義,Windows服務沒有用戶I/O。將錯誤寫入事件日誌,你很好。

+0

我不能在服務的啓動方法中放置一個永無止境的循環,否則服務將無法啓動。所以我正在尋找一些機制來每隔幾分鐘觸發一次作業處理代碼。我設法使用Timer組件並設置其時間間隔,但是當流程運行時,我不得不停止計時器。我通過在啓動過程之前禁用定時器並在過程完成後啓用它來實現此目的。感謝您的回覆。 – RKP 2010-10-11 17:11:18

+0

試試這個:System.Threading.Thread.Sleep(2 * 60 * 1000); – Jay 2010-10-12 14:07:33

0

這是一個更容易使用計劃不是開發自己的應用程序的任務窗口,你應該給它一個嘗試。

如果不工作,你期望的那樣,作爲周杰倫說話的方式,有沒有招了,只記得有沒有GUI。

+0

此服務需要每兩分鐘喚醒一次,而我的公司IT策略不允許計劃任務的睡眠時間少於10分鐘。所以我不得不選擇Windows服務選項。使用控制檯應用程序會更容易,更易於調試。感謝回覆 – RKP 2010-10-11 10:39:01

3

你必須創建控制檯應用程序是這樣的

static void Main(string[] args) 

    { 
     bool createdNew; 
     Mutex m = new Mutex(true, "YourBatchProcessor", out createdNew); 
     if (!createdNew) 
     { 
      Console.WriteLine("YourBatchProcesso is already running!"); 
      return; 
     } 
     //your code goes here 

    } 

和Gmoliv說創建計劃任務比運行,每2分鐘

,或者如果你想寫窗口服務然後像

您的服務代碼
public class YourServrClass 
    { 

    private int numticks = 0; 
    private Timer _timer; 
    private bool _IsStarted; 
    private int Interval =2000; //ticks //2 sec. 
    #region Initializer 
    public YourServrClass() 
    { 
     InitializeComponent(); 
     _timer = new Timer(); 
     _timer.Interval = Interval; 
     _timer.Elapsed += new ElapsedEventHandler(this.Timer_Tick); 
    } 
    #endregion 

    #region Timer_Tick to process 

    private void Timer_Tick(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     numticks++; 
     if (_IsStarted) 
     { 
      _timer.Stop(); 

      //your code //ProcessYourData(); 
      _timer.Start(); 
     } 
    } 
    #endregion 
    protected override void OnStart(string[] args) 
    { 
      _IsStarted=true; 
    } 

    protected override void OnStop() 
    { 
      _IsStarted=false; 
    } 

} 
+0

感謝您的回覆。我通過使用Timer組件解決了它,但是我的代碼有點不同。我在「OnStart」方法中啓動計時器,在「OnStop」方法中停止計時器,並在「Elapsed」事件處理程序中停止計時器,在運行進程之前禁用計時器,並在進程結束後重新啓用計時器。它現在有效。 – RKP 2010-10-11 10:52:42