2013-04-29 43 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