2013-03-27 34 views
0

我正在編寫一個C#服務,它的主要功能是從數據庫中提取照片並將它們保存到一天兩次的目錄中。此操作通常需要大約15分鐘(有很多照片)。如果我把邏輯在OnStart()中運行程序,那麼在啓動服務一分鐘左右後,報告它沒有成功啓動。這是因爲它在OnStart()方法中的時間太長。當計時器倒數到0時調用方法

如何在OnStart()方法中設置一個計時器,在大約一分鐘後調用我的RunApp()方法?

編輯:這是一些代碼。設置好每天運行的調度程序後,我也想簡單地運行它。我想設置一個計時器大約一分鐘就可以工作,這樣就有時間擺脫OnStart()方法。然後,當計時器關閉時,應用程序將運行。

protected override void OnStart(string[] args) 
{ 
    Scheduler sch = new Scheduler("Photo Sync"); 

    try 
    { 
     MailConfiguration mailConfig = new MailConfiguration(Properties.Settings.Default.EmailLogTo, Properties.Settings.Default.EmailLogFrom, 
                  "Photo Sync Photo Service error", Properties.Settings.Default.SmtpServerIp, "Photo Sync"); 
     sch.MailComponent = mailConfig; 
    } 
    catch 
    { 

    } 

    sch.SchedulerFired += new EventHandler(RunApp); 

    try 
    { 
     sch.ScheduleDaily(Properties.Settings.Default.DailyScheduledTime); 
    } 

    RunApp(); 
} 
+2

您可以將保存功能運行在單獨的線程上 - 這樣您就不會殺死服務,因爲啓動時間太長。只需在OnStart中單獨啓動保存。 – Tim 2013-03-27 15:59:44

+1

Google「windows服務計時器」。如果您發佈了一些代碼,我們可以幫助您,但您必須先嚐試。 – Rob 2013-03-27 16:00:12

+1

難道你不能使用[計劃任務](http://support.microsoft.com/kb/308569)? – 2013-03-27 16:00:27

回答

1

在您的服務的OnStart方法中啓動的單獨線程中運行保存功能。事情是這樣的:

protected override void OnStart(string args[]) 
{ 

    // your other initialization code goes here 

    // savePhotos is of type System.Threading.Thread 
    savePhotosThread = new Thread(new ThreadStart(SavePhotos)); 
    savePhotosThread.IsBackground = true; 
    savePhotosThread.Name = "Save Photos Thread"; 
    savePhotosThread.Start(); 

} 

You'll place the functionality for saving the files in the `SavePhotos` method, maybe something like this: 

private void SavePhotos() 
{ 

    // logic to save photos 
} 

我已經用類似的代碼上面做記錄(我日誌統計信息每5分鐘左右的服務)爲永遠在線的服務,我寫了幾年前。不要忘記添加System.Threading到你的服務和using指令。

+0

這工作完美,謝謝!一個簡單的問題是,將IsBackground設置爲true是否重要? – grantmcconnaughey 2013-03-27 16:18:51

+0

根據MSDN,後臺線程和前臺線程之間的區別在於,一旦所有前臺線程完成,應用程序終止,並且所有剩餘的後臺線程都會結束,而不會完成。在你的情況下,我將它設置爲true,以確保保存所有照片的過程完成。看看[Thread.IsBackground屬性](http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx)以獲取更多信息以及顯示差異的示例。 – Tim 2013-03-27 16:24:30

1

通常情況下,正常的流程將啓動Windows服務是讓一個線程,並讓該線程進行相應的業務處理,讓OnStart退出及時爲Windows。線程仍然在後臺處理事物。例如:

protected CancellationTokenSource _tokenSource = null; 

protected override void OnStart(string[] args) 
{ 
    _tokenSource = new CancellationTokenSource(); 

    Task processingTask = new Task(() => 
     { 
      while(!_tokenSource.IsCancellationRequested) 
      { 
       // Do your processing 
      } 
     }); 

    processingTask.Start(); 
} 

protected override void OnStop() 
{ 
    _tokenSource.Cancel(); 
} 

如果您的服務並不需要無限期地運行,那麼你可能要考慮一個計劃任務。

0
System.Threading.Timer Timer1 = new System.Threading.Timer(RunApp, null, 1000, System.Threading.Timeout.Infinite); 

void RunApp(object State) 
{ 
}