2012-03-30 21 views
5

Küçük bir windows hizmetinde arabuluculuk yapmaya çalışıyorum, bu da başlatma sırasında başka bir işlemden sinyal beklemesini sağlıyorum. Elbette, böyle bir yaklaşımın bazen (bazen de) hizmet başlatma zaman aşımına yol açabileceğini biliyorum. Konu bu değil.Windows hizmeti adlandırılmış semaforu göremiyor

Sorun, arabuluculuk amacıyla kullandığım System.Thread.Sempaphore adlı sistemle ilgilidir. Semafor aşağıdaki yapı kullanılarak başka bir yerde yaratılır ve edinilir. Test amaçları için verilen satırın hemen altında yürütmeyi açıkça ihlal ettiğim için, GC'de hiçbir değişiklik yoktur. ( ) Hata ayıklama modunda veya konsol uygulaması altında çalıştırıldığında iyi kod çalışır ardından:

Boolean createdNew; 
System.Threading.Semaphore semaphore = 
    new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew); 
if (createdNew) 
    throw new Exception("That's not what we wanted"); 

Kesinlikle aynı kod Windows hizmetinin bir parçası olarak çalıştırıldığında başarısız: ilgili yardım Lookig Yani

static class Program 
{ 
    static void Main(string[] args) 
    { 
     Boolean createdNew; 
     System.Threading.Semaphore semaphore = 
      new System.Threading.Semaphore(1, 1, "DummyServiceSemaphore", out createdNew); 
     if (createdNew) 
      throw new Exception("That's not what we wanted"); 

     ServiceBase[] ServicesToRun; 
     ServicesToRun = new ServiceBase[] { new Dummy() }; 
     ServiceBase.Run(ServicesToRun); 
    } 
} 

bu.

Not: Mutex'i kullanmayı denedim, ancak bununla ilgili başka bir sorun vardı - beklemede olan uygulama, sahibi Mutex.ReleaseMutex();

GÜNCELLEME: Ben takip eder ve zımbırtı şimdi gayet iyi çalışıyor olarak rutin oluşturmak semaforu kaydetmiştiniz Anurag Ranjhan tepkisi gereğince

:

Boolean newOne = false; 

System.Security.Principal.SecurityIdentifier sid = 
    new System.Security.Principal.SecurityIdentifier(
     System.Security.Principal.WellKnownSidType.WorldSid, 
     null); 

System.Security.AccessControl.SemaphoreSecurity sec = 
    new System.Security.AccessControl.SemaphoreSecurity(); 
sec.AddAccessRule(new System.Security.AccessControl.SemaphoreAccessRule(
    sid, 
    System.Security.AccessControl.SemaphoreRights.FullControl, 
    System.Security.AccessControl.AccessControlType.Allow)); 

System.Threading.Semaphore rootSemaphore = 
    new Semaphore(1, 1, "Global\\DummyServiceSemaphore", out newOne, sec); 

cevap

5

Global\ öneki ile kullanarak deneyin

System.Threading.Semaphore rootSemaphore = 
new System.Threading.Semaphore(1, 1, "Global\DummyServiceSemaphore", out newOne); 

comment section of MSDN

Windows'da adlandırılmış bir Semafor kullanıyorsanız, seçtiğiniz ad Kernel adlandırma yönergeleri tarafından yönetilen şeklindedir. Bu yönergelerin bazıları ayrıca , çekirdek nesnesinin bağlamını tanımlayan Çekirdek Nesne Ad Alanı Adlarını 1 içerir. Varsayılan olarak, Terminal Hizmetleri yüklendiğinde, olaylar gibi kernel nesneleri geçerli Oturumla sınırlıdır. Bu, yapılır; bu nedenle, Terminal Hizmetleri'nde çalışan birden çok oturumda, birbirini etkilemez. Çekirdek Nesnesi Ad alanları, "Yerel \", "Global \" ve "Session \" öneklerini kullanarak, belirli ad alanlarına uygulanabilecek ve iletişimini belirli bir kapsamdaki işlemlerle iletişim kurabilir veya sınırlandırabilecek çekirdek nesneleri oluşturmak için kullanır.

+0

Teşekkür ederiz! Bu sorunu çözdü. – Vitaly

+1

Son zamanlarda aynı sorunu yaşadım ve "Global \" öneki ile bile, bir Windows Hizmeti içinde çalışmasını sağlamak için hala yukarıdaki soru güncellemesinde belirtildiği gibi SemaphoreSecurity nesnesini açıkça belirtmem gerekiyordu. Ancak, bu iş yaptı! – mthierba

İlgili konular