2012-09-21 2 views
2

개체 생성 중 일부 코드를 동기화하기 위해 뮤텍스를 사용하는 C# 응용 프로그램 코드가 있습니다. 객체 생성자는 뮤텍스를 획득하고 객체가 더 이상 필요하지 않을 때 (앱 종료 도중)에만 뮤트를 해제합니다. 따라서 뮤텍스를 해제 할 곳은 객체 소멸자입니다. 문제는 개체 소멸자에서 ReleaseMutex()를 호출하는 중에 예외가 발생한다는 것입니다. 예외는 "비동기 코드 블록에서 객체 동기화 메소드가 호출되었습니다"입니다. 개체 소멸자를 호출하는 gabage 컬렉션을 수행하는 스레드가 처음에는 뮤텍스 (Mutex.WaitOne (false, namedMutex))를 기다리는 동일한 스레드가 아닌 것으로 나타납니다. 이 예외를 피하기 위해 동일한 스레드에서 뮤텍스의 획득과 해제를 어떻게 동기화합니까? 당신의 도움을 주셔서 감사합니다!뮤텍스를 사용하여 C# 개체 동기화 "동기화되지 않은 코드 블록에서 개체 동기화 메서드가 호출되었습니다."오류

public class MyObject 
{ 
    static ExtDeviceDriver devDrv; 
    private Mutex mut = new Mutex(false,myMutex); 

    public MyObject() 
    { 
     mut.WaitOne(); 
     //Thread safe code here. 
     devDrv = new ExtDeviceDriver(); 
    } 

    ~MyObject() 
    { 
     mut.ReleaseMutex(); 
    } 
} 
+1

뮤텍스 보호 란 무엇입니까? 경쟁이란 무엇입니까? 예를 들어, 앱 종료시에만 출시되므로 아무 것도하지 않고 프로세스 종료로 해제 할 수 있습니까? –

+2

이것은 올바른 이유로 잘못된 것을 사용하거나 그 반대의 경우입니다. 잊었다. 어떤 경우 든 동기화 객체를 획득하여 자신의 스레드에서 릴리스해야합니다. 객체의 사용은 실제로 발생한다는 것을 결코 보장 할 수 없다는 것을 의미합니다. 다른 말로하면, 당신의 객체를 생성 한 스레드 (그리고 뮤텍스)가 사라질 수도 있습니다. 더 이상 존재하지 않고 하늘에있는 ThreadPool에서 평생 동안 평온하게 쉬는 것입니다. 앱이 이미 실행 중임을 알 수 있도록 뮤텍스를 획득하는 경우 뮤텍스를 릴리스 할 이유가 없습니다. 그렇지 않으면 [cont'd] –

+0

[계속] 더 많은 정보를 제공하십시오. 그러면 어쩌면 우리가 무엇을하려고하는지 알 수 있습니다. –

답변

3

Dispose pattern을 사용하지 않는 이유는 무엇입니까? MutexWaitHandleWaitHandle에서 IDisposable을 상속합니다. IDisposable을 생성하고 사용하는 클래스가있는 경우 IDisposable을 구현하고 적절히 처리해야합니다. GC가 뮤텍스를 처분하지 못하도록 수동으로 using 블록에서 수행하거나 .Dispose()을 수동으로 호출하십시오. 이렇게하면 누가 언제 무엇을하고 있는지 알 수 있습니다.

을 개체는 IDisposable는 다음 개체가 정리 점점 방법에 대해 생각해야합니다 구현하는 경우 :

This post 당신이 마음에해야 큰 따옴표가있다.

IDisposable을 구현하는 객체는 결정적으로 해제되어야하는 실제 리소스를 보유하고 있기 때문에 일반적으로 그렇게합니다.

여기 정확히 무슨 일이 일어나고 있는지.

또한 이름이 지정된 뮤텍스를 사용하고 있습니다. 명명 된 뮤텍스는 프로세스에서 사용되며 운영 체제 핸들로 관리됩니다. 다른 뮤텍스를 인수하고 릴리스하려고하는 사람이 있습니까? 명명 된 뮤텍스가 필요한 이유가 있습니까? 프로세스가 죽고 뮤텍스가 정상적으로 처리되지 않으면 뮤텍스와 다른 종류의 이상한 것들을 버릴 수 있기 때문에 대개 다루기가 까다 롭습니다.

+1

앱이 여러 인스턴스에서 실행될 수 있습니다. 목적은 후속 인스턴스가 "devDrv = new ExtDeviceDriver()"를 실행하지 않도록하기 위해서 다중 프로세스 (인스턴스)에서 볼 수있는 이름있는 뮤텍스가 필요합니다. 이 인스턴스가 종료되면 후속 인스턴스 중 하나에서 해당 코드 행을 실행하여 외부 드라이버를 처리 할 수 ​​있습니다. – Kevin

+0

확인.하나의 프로세스가 정상적으로 종료하지 않으면 mutex가 일관성없는 상태로 남을 수 있기 때문에 abandonded mutex를 처리해야합니다. 실제로 사용하려는 경우이 모든 것을 처리하는 멋진 래퍼 클래스가 있습니다. https://github.com/blinemedical/Inter-process-mutex – devshorts

+1

도움을 주셔서 감사합니다! – Kevin

관련 문제