2015-02-04 28 views
1

我正在开发一个Windows服务,它执行若干操作,包括侦听多个不同端口上的传入串行端口消息。如何在Windows服务中保持线程打开

通过打开每个串行设备的线程进行侦听。

我仍然想知道如何保持我的线程打开,同时聆听。 我尝试了一些像while(true){}循环的东西,但它有效,但在连接多个设备时将cpu占用100%。

在控制台应用程序中,我可以使用console.readline(),我正在寻找类似和容易的东西。

这就是我现在拥有的,我如何使它工作?

public static void Start() 
    { 
     var devices = MyService.Kernel.Get<IDevicesService>(); 
     foreach (var device in devices.ComDevices.List()) 
     { 
      var thread = new Thread(() => StartKeypadThread(device.Id)); 
      thread.Start(); 
     } 
    } 

    public static void StartKeypadThread(int deviceId) 
    { 
     var devices = MyService.Kernel.Get<IDevicesService>(); 
     var device = devices.ComDevices.Find(deviceId); 
     var c = new SerialConnector(device); 
     c.SerialDataRecieved += c_SerialDataRecieved; 
     c.Start(); 
     //Console.ReadLine(); --> I know, sounds stupid, it's a Service :) 
     //while (true) 
     //{ 
     //} 
    } 
+1

没有必要使用一个线程,当你有一个“DataReceived”事件。请不要使用该事件并调用常规阻止Read()或不要使用线程。并且观察服务中对OnStart/OnStop的需求,您总是需要一个AutoResetEvent来检测服务应该暂停还是停止。你可以调用它的WaitOne()方法来阻塞线程。 –

+0

@Hans说什么。您不必让程序在服务的OnStart()方法中运行,事实上,您应该尽快从中返回。您的程序将继续运行,直到服务停止。 – CodeCaster

回答

0

谢谢大家的帮助。 我没有经验的线程,所以也许我确实不需要使用这些线程,但是当我没有,我得到了一个错误“安全处理已关闭”在服务的另一部分(我didn不使用这些Com设备)。

为了快速解决问题并继续使用这些线程,我通过使用WaitHandler发现了另一个解决方案。

如果有人需要它,这是我如何做的:

public static void Start() 
{ 
    var devices = MyService.Kernel.Get<IDevicesService>(); 
    foreach (var device in devices.ComDevices.List()) 
    { 
     var thread = new Thread(() => StartKeypadThread(device.Id)); 
     thread.Start(); 
    } 
} 

public static void StartKeypadThread(int deviceId) 
{ 
    var devices = MyService.Kernel.Get<IDevicesService>(); 
    var device = devices.ComDevices.Find(deviceId); 
    var c = new SerialConnector(device); 
    c.SerialDataRecieved += c_SerialDataRecieved; 
    c.Start(); 
    var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Guid.NewGuid().ToString()); 
    waitHandle.WaitOne(); 
} 
+1

这个WaitHandle方法和睡眠是一样的。它只是永远挂起。不需要使用命名句柄。也许问题是SerialConnector对象是GC?把它们放到全局/静态列表中,让所有的线程退出。现在你使用每个线程作为GC句柄... – usr

0

字面上回答:Thread.Sleep(Timeout.Infinite)

为什么你需要“挂”线程,但是,特别是永远?也许你应该使用当你想停止服务时发出的ManualResetEvent。

另外,不需要启动所有这些子线程来附加事件。其中每个将运行1ms左右,然后退出。浪费时间。

+0

那么它不需要挂在前面,它必须永远听,睡不好对此。 –

+0

@RubinhoG。你在说什么?睡一根线不会影响另一根线。 – usr

+0

如果它睡觉了,它是否仍然可以处理该线程中的c_SerialDataRecieved事件? 无论如何,它现在的作品,没有线程和服务的经验,我很高兴它的作品:) –