2012-08-08 2 views
0

공동 작업자는 Sparkfun RFID 판독기에 연결되는 Processing을 사용하여 프로토 타입을 작성했으며 USB를 통한 직렬 연결을 사용한다고 생각합니다. 우리는 프로토 타입을 다수의 평가판 집에 배치했으며, 사용자 전환은 간과하게 간과되는 일반적인 사용 시나리오 중 하나입니다. 따라서 프로토 타입 응용 프로그램의 한 인스턴스 만 시스템의 모든 사용자에게 실행되도록하는 래퍼를 작성하고 있습니다.EventWaitHandle을 사용하여 여러 사용자간에 단일 인스턴스 보장

간단한 콘솔 앱으로 내 첫 번째 테스트를 테스트하고 있습니다. 여기에 코드입니다 :

static void Main(string[] args) 
    { 
     // http://stackoverflow.com/a/2590446/575530 
     var users = new SecurityIdentifier(WellKnownSidType.WorldSid, null); 
     var rule = new EventWaitHandleAccessRule(users, EventWaitHandleRights.FullControl, AccessControlType.Allow); 
     var security = new EventWaitHandleSecurity(); 
     security.AddAccessRule(rule); 
     bool createdStartup; 
     using (var whStartup = new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppStartupEvent", out createdStartup, security)) 
     { 
      bool createdShutdown; 
      using (var whShutdown = new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppShutdownEvent", out createdShutdown, security)) 
      { 
       Console.WriteLine("Let other instances shutdown"); 
       whStartup.Set(); 
       Console.WriteLine("If other instances exist wait for them to shutdown"); 
       if (!createdShutdown) 
       { 
        whShutdown.WaitOne(); 
       } 
       whShutdown.Reset(); 
       Console.WriteLine("Start tray app"); 
       var tokenProc = Process.Start(@"C:\Temp\FAMILY3_WIN\TokensApp.exe"); 
       Console.WriteLine(tokenProc.ProcessName); 
       Console.WriteLine("Wait to see if another instance to tries to start"); 
       whStartup.Reset(); 
       whStartup.WaitOne(); 
       Console.WriteLine("Shutdown if another instance starts"); 
       //if (tokenProc != null) tokenProc.Kill(); 
       foreach (var process in Process.GetProcesses()) 
       { 
        if (process.ProcessName.StartsWith("javaw")) 
        { 
         process.Kill(); 
        } 
       } 
       whShutdown.Set(); 
      } 
     } 
     Console.WriteLine("Done..."); 
     Console.ReadLine(); 
    } 

(NB 나는 문제는이 코드가 알고 주위 (1) 실행 프로토 타입 (2) 동시에 시작하는 경우가 많이 응답 할 코드가 없습니다없는 Java 프로세스를 죽이고, 한 번에 두 가지.하지만 내 질문에 관한 것은 아닙니다.)

단일 사용자 계정으로 테스트하면 정상적으로 작동합니다. 내 애플 리케이션을 시작할 수 있습니다, 차례 차례로 프로토 타입을 시작하고 만약 내가 내 애플 리케이션의 두 번째 인스턴스를 다시 프로토 타입의 다른 인스턴스를 시작하기 전에 첫 번째 프로토 타입의 초기 인스턴스를 죽일 내 애플 리케이션의 두 번째 인스턴스를 시작합니다.

하지만 두 개의 다른 사용자 계정에서이 작업을 시도하면 실패합니다 (자동으로). 내가

  1. 내 응용 프로그램의 인스턴스를 시작하면 프로토 타입을 시작
  2. 사용자 전환
  3. 시작 내 응용 프로그램의 인스턴스가 다음 먼저 종료 1 단계에서 내 응용 프로그램없이 프로토 타입을 시작 기존 예.

누구든지 내 코드에 문제가있는 것을 볼 수 있습니까? 동일한 컴퓨터에서 여러 개의 동시 사용자 세션에서 EventWaitHandle을 어떻게 사용해야합니까?

+2

여기서 이벤트 개체가 적절한 개체가 아니며 해결할 수없는 경쟁 조건이 있습니다. 뮤텍스를 사용하는 것은 상용구입니다. 프로세스가 먼저 도착했음을 알려주는 * createdNew * bool을 반환하는 생성자가 있습니다. –

+0

재미있는 한스. 두 번째 앱이 시작될 수있는 메커니즘으로이 경우 경쟁 조건으로부터 상대적으로 안전하다고 생각합니다. 두 개의 뮤텍스를 사용하기 시작했지만 이벤트로 바뀌 었습니다. 좀 더 살펴 보겠습니다. – dumbledad

답변

0

긴 질문을 작성한 후 몇 분이 지났는데도 항상 답답합니다.

나는 EventWaitHandle의 이름으로 슬래시를 잘못 처리했다. 이 하나

new EventWaitHandle(false, EventResetMode.AutoReset, "Global/AaltoTokensAppShutdownEvent", out createdShutdown, security) 

: 예를 들어 생성자 호출을 대체

new EventWaitHandle(false, EventResetMode.AutoReset, @"Global\AaltoTokensAppShutdownEvent", out createdShutdown, security) 

수정 내 문제를.

관련 문제