2014-02-27 1 views
7

내가 쓰고있는 소프트웨어에서 (USB를 통해 연결된) 외부 장치에서 일부 데이터를 읽습니다. 내가받은 드라이버 (dll 파일)는 스레드로부터 안전하지 않으며 한 번에 하나의 인스턴스 만 사용할 수 있습니다. C#에서 이러한 드라이버에 대한 래퍼를 작성해야합니다. 나는 다중 스레드 응용 프로그램을 감안할 때, 내가 있는지 확인하고 싶습니다 : (? 싱글 인 아마 래퍼)우리가 하나의 인스턴스 만 가지고 올바른 방법으로 처리하는 방법

  1. 항상 하나의 인스턴스 만이 사용됩니다 드라이버를 해제 처분 할 수
  2. 및 이 자원 (는 IDisposable?)

Disposable Singleton에서 나는 의견이 나누어집니다 것을 볼 수 있습니다 싱글 톤으로 IDisposable 여부가 될 수 있습니다. 어쩌면 둘 다 더 나은 해결책이 있을까요? 도움을 환영합니다.

using System; 
using System.Runtime.InteropServices; 

namespace Philips.Research.Myotrace.DataReading.Devices 
{ 
    class MyDevice: IDisposable 
    { 
     private static volatile MyDeviceInstance; 
     private static object SyncRoot = new Object(); 

     private bool disposed = false; 

     private MyDevice() 
     { 
      //initialize unmanaged resources here (call LoadLibrary, Initialize, Start etc) 
     } 

     public MyDevice GetInstance() 
     { 
      if (Instance == null) 
      { 
       lock (SyncRoot) 
       { 
        if (Instance == null) 
        { 
         Instance = new MyDevice(); 
        } 
       } 
      } 

      return Instance; 
     } 

     public void Dispose() 
     { 
      this.Dispose(true); 
     } 

     protected virtual void Dispose(bool disposing) 
     { 
      if (!this.disposed) 
      { 
       if (disposing) 
       { 
        //dispose of unmanaged resources here (call Stop and Close from reflection code 

        Instance = null; 
       } 

       this.disposed = true; 
      } 
     } 

     [DllImport("devicedrivers.dll")] 
     private static extern bool Initialize(); 
     [DllImport("devicedrivers.dll")] 
     private static extern bool LoadLibrary(); 
     [DllImport("devicedrivers.dll")] 
     private static extern bool Start(); 
     [DllImport("devicedrivers.dll")] 
     private static extern bool Stop(); 
     [DllImport("devicedrivers.dll")] 
     private static extern bool Close(); 
     //and few more 
    } 
} 
+6

실제로 처분해야합니까? 언제 그렇게 할거 니? 아마도 응용 프로그램의 끝 부분에서만 - 그리고 프로세스가 사라지면 왜 명시 적으로 해제 귀찮게합니까? (자동으로 실행됩니다.) 싱글 톤 패턴을 더 단순하게 만들려면 http://csharpindepth.com/Articles/General/Singleton.aspx를 읽고 싶을 수도 있습니다. –

+0

적절한 종료 함수 (드라이버 소스의 문서 없음)를 호출하지 않으면 관리되지 않는 코드가 어떻게 동작 할 것인지 확신 할 수 없습니다. –

+1

OS는 일반적으로 프로세스 종료시 관리되지 않는 리소스를 정리할 책임이 있습니다. 프로세스 기간 동안 열린 상태로 유지하려는 리소스의 경우 정상이어야합니다. –

답변

3

운영 체제 프로세스가 종료 될 때 관리되지 않는 리소스를 정리에 대한 책임 : 지금은
나는 다음과 같은는 IDisposable 싱글 있습니다. 그래서 리소스가 프로그램 종료 전까지 리소스를 처음 사용할 때부터 할당 받게되면 기꺼이 리소스가 할당됩니다. IDisposable을 전혀 구현하지 않을 것입니다.

그렇지만 테스트 가능성을 위해 공개적으로 싱글 톤을 노출시키지 않을 가능성이 높습니다. 인터페이스를 만들고 종속성 삽입을 사용하여 코드 전체에 동일한 인스턴스를 주입하는 것을 고려하십시오. 나는 일반적으로 싱글 톤을 싫어한다. 만약 당신이 하나를 사용하려고한다면, 나는 내 article on singletons에있는 이후 패턴 중 하나를 따르라고 제안 할 것이다. 이 이중 체크 된 모든 말도 안되는 말들을 피하십시오 :)

+0

나는 싱글 톤에 관한 기사가 훌륭하다고 말하고 깜짝 놀랐다. 귀하의 의견을 보내 주셔서 감사합니다. –

0

직접 쓰는 정적 싱글 톤을 사용하지 말고, 현재 연결되어있는 장치를 캡슐화하는 IDisposable 개체 (또는 개체 목록)를 반환하는 메서드가 있어야합니다.). 대부분 단일 스레드 작업으로 제한되는 많은 USB 드라이버는 멀티 스레딩이 허용되는 단일 상황을 갖습니다. 모든 스레드는 드라이버 인스턴스가 종료되도록 요청할 수 있으며 보류 중이거나 이후 작업이 처음에 중단되도록합니다. 셧다운은 즉각적이지 않을 수 있으며 "갇힌"장치를 셧다운하고 다시 시작하려면 다시 종료 시도가 실패하거나 종료가 완료되기 전에 발급 될 경우 차단 될 수있는 가능성에 대비해야합니다.

OS가 종료 될 때 프로그램이 사용하고있는 USB 장치 드라이버를 정리하려고 시도하지만 이러한 정리가 항상 작동하는 것은 아니므로 의존하지 않을 것입니다. 더 이상 필요 없다는 것을 알 때 할 수있는 일을 처분하는 것이 좋습니다. 추상화의 관점에서, 연결된 장치를 식별하는 싱글 톤 방법을 사용하는 경우 식별 된 장치를 배치하는 데 아무런 문제가 없습니다. 일단 장치가 폐기되면 연결을 재설정하기 위해 무언가가 완료 될 때까지 목록에 더 이상 나타나지 않습니다.

관련 문제