2013-04-29 52 views
1

我有一個服務創建一個線程,該線程應該運行直到互斥體由另一個進程發送信號。我在我的服務代碼以下打開一個與服務共享的互斥體

 private readonly Mutex _applicationRunning = new Mutex(false, @"Global\HsteMaintenanceRunning"); 

     protected override void OnStart(string[] args) 
     { 
      new Thread(x => StartRunningThread()).Start(); 
     } 

     internal void StartRunningThread() 
     { 
      while (_applicationRunning.WaitOne(1000)) 
      { 
       FileTidyUp.DeleteExpiredFile();  
       _applicationRunning.ReleaseMutex(); 
       Thread.Sleep(1000); 
      } 

     } 

現在我應該要求互斥鎖,並迫使while循環控制檯應用程序要退出

 var applicationRunning = Mutex.OpenExisting(@"Global\HsteMaintenanceRunning"); 
     if (applicationRunning.WaitOne(15000)) 
     { 
      Console.Write("Stopping"); 
      applicationRunning.ReleaseMutex(); 
      Thread.Sleep(10000); 
     } 

當控制檯應用程序試圖打開互斥我收到錯誤「由於被廢棄的互斥體而等待完成」。這裏有什麼問題?

+0

一個被遺棄互斥體意味着一個線程在釋放它對互斥鎖的保留之前被終止。這讓我想知道你的服務的DeleteExpiredFile()方法是否拋出一個異常,並因此阻止互斥體被正確釋放。 – RogerN 2013-04-29 14:54:59

+0

在那一刻該方法除了返回0之外什麼也不做。它只是一個佔位符,代碼可能會在我有互斥鎖工作後進行。對不起,我很抱歉 – John 2013-04-29 15:01:34

回答

1

我建議您使用服務的內置停止信號而不是互斥鎖。互斥類更適合管理對共享資源的獨佔訪問,這不是這裏發生的事情。你也可以使用系統事件,但由於服務已經有一個內置的機制來發出停止信號,爲什麼不使用它呢?

您服務的代碼應該是這樣的:

bool _stopping = false; 
Thread _backgroundThread; 
protected override void OnStart(string[] args) 
{ 
    _backgroundThread = new Thread(x => StartRunningThread()); 
    _backgroundThread.Start(); 
} 
protected override void OnStop() 
{ 
    _stopping = true; 
    _backgroundThread.Join(); // wait for background thread to exit 
} 
internal void StartRunningThread() 
{ 
    while (!stopping) 
    { 
     FileTidyUp.DeleteExpiredFile(); 
     Thread.Sleep(1000); 
    } 
} 

然後,控制檯應用程序將需要使用框架的ServiceController的類來發送關閉消息給你的服務:

using System.ServiceProcess; 
... 
using (var controller = new ServiceController("myservicename")) { 
    controller.Stop(); 
    controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(15.0)); 
} 
+0

好點!謝謝 – John 2013-04-29 16:50:24