2014-08-27 3 views
-1

요약 :버려진 뮤텍스를 제거하려면 어떻게해야합니까?

를 생성 한 프로세스가 죽고 경우 뮤텍스를 취소 할 수있는 방법이 있나요?

상세 사항 :

나는 확인하기 위해 뮤텍스를 사용하는 내 응용 프로그램 실행의 한 인스턴스입니다.

자동 업데이트를 수행하기 위해 새로운 코드를 테스트하는 동안 Environment.Exit (0)을 실행했습니다. 디버그 모드에서 실행되는 동안, 내 뮤텍스가 정상적으로 정리되었습니다.

하지만 '릴리스'로 빌드를 변경하면 다음 뮤텍스는 통화 종료 후 주위의 유지 및 포기로 표시됩니다 :

Abandoned Mutex

나는 두 번이 아니라는 것을 확인하기 위해 검사 한 이 뮤텍스가 첨부 된 프로세스가 계속 실행 중입니다.

지금 내 앱을 실행할 때마다 뮤텍스가 계속 존재하며 내 앱이 실행되지 않는다고 생각합니다. (그 자체를 보여주기 위해 응용 프로그램의 "현재 실행중인"인스턴스에 메시지를 보내려고하기 때문에 그것은 또한 충돌합니다.) 나는이 같은 뮤텍스를 해제하려고

:

bool createdNew; 
string applicationId = "18773:TestStudio"; 
var singleInstanceMutex = new Mutex(true, applicationId, out createdNew); 

singleInstanceMutex.Close(); // Tried ReleaseMutex() too 

하지만 과정을 그 그냥 그것을 가져오고 그것을 해제합니다.

내가 재부팅 할 수 있다는 것을 알고 있지만, 프로덕션 환경에서 이러한 문제가 발생할 경우를 대비하여 더 나은 해결 방법을 찾고 있습니다.

뮤텍스를 만든 프로세스가 종료되어 사라진 경우 뮤텍스를 지우는 방법이 있습니까?

이 실제로 당신의 질문에 대한 대답, 그러나 여기에서 나는이 목적을 위해 사용하는 코드의 경우
+3

귀하의 스크린 샷에 따르면 3 가지 사항이 여전히이를 참조하고 있습니다. 핸들이있는 3 가지 것들을 모두 닫습니다. –

+0

@Scott Chamberlain - 참고 문헌은 그대로 남아 있지만 프로세스는 오래 전에 사라졌습니다. 그것은 참조를 해제하지 않은 방식으로 사망했다. 따라서 뮤텍스를 해제하는 방법에 대한 내 질문. – Vaccano

+0

@ Vccano 그러면 두 가지 상황 중 하나가 발생합니다. 손상된 OS 설치 또는 무언가가 참조를 가지고 있다는 것을 깨닫지 못합니다. 정말 실패했다면 카운트는 0이 될 것이고, 실패한 프로세스의 핸들 정리는 Windows 95 (또는 98, 나는 기억할 수 없다)에서 다시 수정되었습니다. 프로그램이 실제로 죽지 않았거나 죽었거나 다른 프로그램 (IIS, 바이러스 백신, 누가 아는 사람)이 핸들을 잡아서 놓아 두지 않는다고 생각할 때 프로그램이 실제로 작동하지 않는 것입니다. –

답변

0

모름 :

// Mutex object used to determine if there are multiple instances of this program running. 
    // Note that this is a reference to a .Net Mutex object, not the Windows mutex itself. 
    private static Mutex _onlyOneInstanceMutex; 



    /// <summary> 
    /// Method to test that there is not another instance of the program already running on this 
    /// machine, or at least in this Terminal Services session or Windows Vista/Windows 7 
    /// concurrent sessions session. If there is, a message box-style localized error message is 
    /// displayed and the value false is returned. This implies that this method should not be 
    /// used in programs that are run as a Windows service. 
    /// 
    /// This implementation uses a .Net Mutex object in public storage to prevent it from being 
    /// garbage-collected. The name of the associated Windows mutex is simply the program name as 
    /// provided by the caller. Neither the .Net Mutex object nor the Windows mutex are ever 
    /// explicitly released; they remain in existence, perhaps in an "abandoned" state, until the 
    /// process that created them terminates. 
    /// </summary> 
    /// <returns>false if another instance running, otherwise true</returns> 
    [SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive", 
        Justification = "Not sure if this is correct or not.")] 
    public static bool TestOnlyOneInstance(string programName) 
    { 
    // Funny construct to prevent the Mutex from being garbage collected 
    GC.KeepAlive(_onlyOneInstanceMutex); 

    // Test if we are the first instance, and if so create the Windows mutex, making it 
    // impossible for subsequent instances to successfully create their mutex 
    bool firstInstance; 
    _onlyOneInstanceMutex = new Mutex(false, programName, out firstInstance); 
    if (firstInstance) 
     return true; 

    // Display a (possibly localized) error message, then return 
    string errorMessage = MLocalizer.GetString("Error1", 
      "Another instance of this program is already running on this machine.") + 
     "\n" + MLocalizer.GetString("Error2", 
            "You cannot run two instances at the same time.") + 
     "\n" + MLocalizer.GetString("Error3", "Please use the other instance."); 
    MessageBox.Show(errorMessage, programName, MessageBoxButtons.OK, MessageBoxIcon.Error); 
    return false; 
    } 

편집 :

만 차이가 나는 내 코드에서 볼 수 있으며, 당신은 "처음 소유"를 false로 지정하고 가비지 수집에 대해 재미있는 점이 있습니다.

오, 나는 뮤텍스를 정적이라고 선언합니다.

관련 문제