2015-02-04 75 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事件? 無論如何,它現在的作品,沒有線程和服務的經驗,我很高興它的作品:) –