2013-03-27 92 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) 
{ 
}