2012-08-10 4 views
1

ASCOM 망원경 드라이버를 쓰고 있는데 명령을 범위로 보내서 클라이언트 응용 프로그램 이 제대로 연결이 끊어 지거나 충돌이 발생해도 범위가 이동하지 않도록해야합니다. . C# finalizers에서 코드 실행 보장

나는 그것이 SendSerialPortCommand() 메소드로 만드는이

~Telescope() 
{ 
    Common.AbortSlew(); 
    Common.SetTracking(false); 
} 

같이 보입니다하고 실제로 와이어에 바이트를 발송하지 않고 종료하고 이전에 바로 종료 보인다 종료자를 추가하는 시도 lock 문.

의 repo는 여기에서 볼 수 있습니다

http://code.google.com/p/ascom-nexstar-telescope/source/browse/NexStar/

종료자를 호출 방법

는 이러한 목표를 달성하기 위해 더 이상 신뢰할 수있는 방법이 정적 클래스에서 흔히 driver.cs에?

답변

4

IDisposable 인터페이스를 구현하고 Dispose 메서드로 작업하십시오.

당신은 그렉 비치에서이 문서를 참조한다 : 대신 소멸자의 Implementing and using the IDisposable interface

을, .NET은 (기본 Object 클래스 에 정의 된 Finalize 메서드를 오버라이드 (override) 에 의해 구현되는 파이 나라를 가지고 C#을 다소 혼동을 사용하지만 C++ 소멸자 구문 ~ Object ). 개체가 범위에서 벗어난 경우 이 GC에 의해 수집되는 대신 Finalize 메서드를 재정의하면 GC는 마무리 메서드 큐 에 배치합니다. 다음 GC주기에서 큐 의 모든 종료 기가 실행되고 (현재 구현의 단일 스레드에서) 완료된 개체의 메모리가 회수됩니다 ( ). 에서 마무리자를 정리하고 싶지 않은 이유는 분명합니다. 두 개의 GC 주기를 사용하여 객체를 수집하는 대신 하나의 스레드가 있으며 모든 스레드가 실행되는 동안 모든 종료 기가 실행됩니다. 일시 중지되었으므로 성능이 저하 될 수 있습니다.

따라서 소멸자가없고 마무리 도구에 정리를 남기고 싶지 않은 경우 수동으로 개체를 정리하는 것이 유일한 옵션입니다. 이 기능을 지원하기위한 표준을 제공하는 IDisposable 인터페이스를 입력하고 개체에 대한 정리 논리를 넣는 Dispose라는 단일 메서드를 정의합니다. finally 블록 내에서 사용될 때이 인터페이스 은 소멸자와 동일한 기능을 제공합니다. 코드에서 finally 블록의 이유는 기본적으로 IDisposable 인터페이스를 지원하기위한 것입니다. 이것이 C++이 destructors를 가진 finally 블록을 위해 을 필요로하지 않기 때문에 try/except를 사용하는 이유이다.

+0

이 문제의 근본 원인은이 문제의 근본 원인은 드라이버를 사용하는 응용 프로그램이 관리되지 않는 C++이고 드라이버가 C#에서만 관리되므로 ~ Telescope()가 호출되고 I Connected 속성을 false로 설정하여 관리되지 않는 C++ 응용 프로그램이 드라이버에서 제대로 연결을 끊도록 할 수있는 권한이 없습니다. – user964078

1

응용 프로그램을 모니터링하고 종료되거나 충돌이 다시 시작될 때 서비스를 작성할 수 있습니다.

0

IDisposable을 구현하는 것이 API에 매우 좋습니다.
나는 또한 귀하의 드라이버와 ASCON 사이에있는 프록시 서비스를 작성하는 것을 고려할 것입니다.
작업 관리자를 통한 안전하지 않은 중지은 여전히 ​​잘못된 중지로 이어질 수 있습니다.

0

OK, 문제 내 관리되는 C#을 ASCOM 드라이버가 false로 다음 나가는 연결 속성을 설정하여 드라이버에서 제대로 분리하지 것이다 관리되지 않는 C++ 응용 프로그램에서 사용되는, 그래서 내가 사용하려고 한 것이 었습니다 C#을 finalizer이 사건을 잡으려고하고 아마 종료 코드에서 관리 객체를 참조하는 작동하지 않는 범위를 중지합니다.

해결 방법은 appdomain.currentdomain.processexit 이벤트를 사용하여 종료 자/소멸자가 실행되기 전에 내 시스템 종료 코드 을 실행하는 것입니다.