2012-04-25 26 views
1

我设计了一个应用程序,开始一个无尽的Thread。此Thread正在通过SOAP-API从特定设备收集事件,并在发生特定事件时执行各种方法。
现在我希望所有这些都作为服务运行,但我不确定如何设计应用程序。C#服务应用程序启动无尽线程

我目前的计划是有服务。该服务创建了一个“poller”类的实例,收集信息。之后,创建一个线程,该线程始终执行“轮询器”的轮询功能。是否应在我的服务应用程序的OnStart事件中创建并执行“轮询器”实例和线程?我是否必须在OnStop事件中停止线程?或者会有更聪明的设计?

我不确定这个,因为我读过,OnStart事件不应该永久执行。但是,如果我从这里拨打Thread,它会永久执行吗?

感谢您的帮助,因为这是我的:-)

+2

你需要自己去一个,然后在遇到它们时回到特定的问题。 – Nick 2012-04-25 08:20:58

回答

4

的“轮询”类将被从您所创建的轮询线程使用,让你有一些选择第一服务应用。我可能会去在poller类ctor中创建轮询线程 - 似乎没有理由让线程有更大的范围。如果添加了更多设备,您只需创建更多轮询实例即可。

在OnStart()中,创建一个轮询实例(它自己创建轮询线程)并返回,因此满足'OnStart-Event不应该永久执行'的条件。

在OnStop()中停止线程?首先,尝试停止线程的首选方法 - 不要尝试去做。当服务管理器或任务管理器关闭时,您的服务是否正常运行并立即停止?如果是这样,不要使不必要的,并可能适得其反的工作,试图明确停止在OnStop()或轮询类dtor中的轮询线程。只需将OnStop()留空并查看它是否正常工作。

如果你发现你必须在服务进程被操作系统杀死之前终止一个线程,你可能不得不采取狡猾的手段来说服轮询线程立即退出,否则你可能会逃脱Thread.Interrupt ()。取决于..

刚看到,我尝试这样做:

class poller 
{ 
    public static void ThreadProc() 
    { 
     for (;;) 
     { 

      Thread.Sleep(0); 
     } 
    } 
    Thread myThread; 
    public poller(){ 
     myThread = new Thread(new ThreadStart(ThreadProc)); 
     myThread.Priority = ThreadPriority.BelowNormal; 
     myThread.Start(); 
    } 
}; 

class WindowsService : ServiceBase 
{ 
    poller thisPoller; 
    public WindowsService() 
    { 
     this.ServiceName = "My Windows Service"; 
     this.EventLog.Log = "Application"; 

     this.CanHandlePowerEvent = true; 
     this.CanHandleSessionChangeEvent = true; 
     this.CanPauseAndContinue = true; 
     this.CanShutdown = true; 
     this.CanStop = true; 
    } 
    protected override void OnStart(string[] args) 
    { 
     base.OnStart(args); 
     thisPoller = new poller(); 
    } 
    protected override void OnStop() 
    { 
     base.OnStop(); 
    } 

它内置并与一些项目属性摆弄和运行installUtil的正确版本后安装成功。它开始OK,睡眠(0)循环显然是工作的,因为服务出现在'进程'选项卡上,在我的i7上CPU使用约17%。当我在任务管理器服务中选择“停止服务”时,服务状态直接进入“停止”状态,但进程消失约20秒(?)。

为了更好玩,我真的装上了箱子。我停止了服务,卸载与重建:

protected override void OnStart(string[] args) 
{ 
    base.OnStart(args); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
    thisPoller = new poller(); 
} 

当我重新安装和重新启动,我知道这是工作,因为我能听到CPU风扇加快转速之前,我可以得到任务管理器。果然,所有8个核心都100%。

即使使用8个CPU循环线程,停止也没有问题。再次,状态立即进入“停止”状态,过程在20秒后消失。

将睡眠时间间隔设置为'1000000',以便线程不运行也没有任何问题 - 开始确定,停止确定。

+0

非常感谢你!这对我有很大帮助!我只有一个问题:在创建轮询实例时如何“返回”,以便OnStart()不会永远执行? – MartiniMoe 2012-04-25 10:32:38

+0

只需创建一个轮询实例并退出onStart()。你可以声明一个'poller * thisPoller';'变量在Service类的顶部,'thisPoller = new poller(URL)';'在OnStart()中。 – 2012-04-25 12:33:35

+0

非常感谢你为这个非常详细的答案!你帮了我很多!对不起,我不能'投票'你的答案,因为我没有15声望:-( – MartiniMoe 2012-04-26 07:41:04

相关问题