2016-09-28 4 views
0

스레딩 here과 관련하여이 기사를 읽었습니다. Mutex 섹션에 다음 코드가 있습니다. 나는이 코드 내가 EXE (위의 생성 된 EXE)를 실행하면 두 번이 를 인쇄해야합니다, 예상대로 작동하지 않는 실행할 때블록을 사용하여 뮤텍스가 다르게 동작합니다.

class OneAtATimePlease 
{ 
    static void Main() 
    { 
    // Naming a Mutex makes it available computer-wide. Use a name that's 
    // unique to your company and application (e.g., include your URL). 

    using (var mutex = new Mutex (false, "oreilly.com OneAtATimeDemo")) 
    { 
     // Wait a few seconds if contended, in case another instance 
     // of the program is still in the process of shutting down. 

     if (!mutex.WaitOne (TimeSpan.FromSeconds (3), false)) 
     { 
     Console.WriteLine ("Another app instance is running. Bye!"); 
     return; 
     } 
     RunProgram(); 
    } 
    } 

    static void RunProgram() 
    { 
    Console.WriteLine ("Running. Press Enter to exit"); 
    Console.ReadLine(); 
    } 
} 

는 그러나 "다른 응용 프로그램 인스턴스는 안녕. 실행 중입니다!". 그러나 그 블록으로가는 것은 아닙니다.

그러나 사용하는 블록을 제거하면 코드가 예상대로 올바르게 동작합니다.

도와주세요. 나는 스레딩 개념에 익숙하지 않다.

UPDATE 오해의 소지에 대한

죄송합니다. 나는 실제로 그 기사에 정확하게 쓰여진 것처럼하지 않았다.

내 코드로되고,

internal class Program 
{ 
    /// <summary> 
    /// Entry point 
    /// </summary> 
    /// <param name="args">The arguments.</param> 
    internal static void Main(string[] args) 
    { 
     //Misc.RunAssemblies(); 

     var threadingDemo = new ThreadingDemo(); 
     threadingDemo.MutexDemo(); 

     Console.ReadLine(); 
    } 
} 

namespace LearnNet.Console 
{ 
    using System.Threading; 

    public class ThreadingDemo 
    { 
     public void MutexDemo() 
     { 
      using (var mutex = new Mutex(false, "Global\\oreilly.com OneAtATimeDemo")) 
      { 
       // Wait a few seconds if contended, in case another instance 
       // of the program is still in the process of shutting down. 
       if (!mutex.WaitOne(0, false)) 
       { 
        System.Console.WriteLine("Another app instance is running. Bye!"); 
        return; 
       } 

       RunProgram(); 
      } 
     } 

     static void RunProgram() 
     { 
      System.Console.WriteLine("Running. Press Enter to exit"); 
     } 
    } 
} 

이 제가 위에서 설명 된 문제를 재생한다. 그리고 내가 사용하는 블록을 제거하면 올바르게 동작합니다.

+0

첫 번째 코드가 제대로 작동하고 두 번째 인스턴스를 실행할 때 "Bye"가 인쇄됩니다. – Evk

+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 문제가 생겼어. 나는 그 소식을 업데이트 할 것이다. – shanmugharaj

+0

@Evk 업데이트 된 질문을 확인하십시오. 문제가 재현됩니다. – shanmugharaj

답변

1

뮤텍스가 어떻게 작동하는지 이해해야합니다. WaitOne을 획득하면 ReleaseMutex또는 처분시이 출시됩니다. 블록 사용 끝에서 (제어 흐름이 나올 때), 뮤텍스는 폐기됩니다 (그래서 블록을 먼저 사용하는 것이 그 이유입니다). 업데이트 된 코드에서 뮤텍스를 가져온 다음 RunProgram 문 뒤에 즉시 릴리스하고 모든 후속 인스턴스도 즉시 가져 와서 릴리스합니다.

블록을 사용하지 않을 때는 Dispose 뮤텍스가 없으므로 뮤텍스를 해제하지 마십시오. Console.ReadLine 명령문이 실행될 때 - 프로세스는 여전히 뮤텍스를 보유합니다. 프로세스가 끝나면 뮤텍스가 여전히 릴리스되지만 아주 좋은 방법은 아닙니다. 뮤텍스를 명시 적으로 해제하는 것이 더 좋습니다.

게시 한 첫 번째 코드 (업데이트 전)에서 작동하는 이유는 무엇입니까? Console.ReadLine() 문이 블록을 사용하여 내부에 있으므로이 명령문의 제어 흐름 블록에 프로세스가 여전히 뮤텍스를 보유하고 있습니다.

+0

Ohh 내 잘못입니다. 나는 그것이 지금 명백하다는 것을 이해한다. 실제로 나는 내가 로직을 클래스와 분리 한 코드에서 Console.ReadLine을 놓친 것을 보지 못했다. 아주 멍청한. 시간을 낭비해서 죄송합니다. 감사! – shanmugharaj

관련 문제