일반 개요 내가 4 개 주 기능이 기본 API와 결합 할 필요가강제 종료자를 주문
:
void ActivateEngine();
int CreateModule();
void DestroyModule(int id);
void TerminateEngine();
그리고 문서 ActivateEngine
및 TerminateEngine
이 CreateModule
에 모든 통화를 둘러싸고해야한다고 주장하고 DestroyModule
. 나는이 .NET 객체의 DllImport
속성을 사용하여 네이티브 API에 바인더 제본 즉 Engine
및 Module
을 모두 만든이 작업을 수행하려면
void foo()
{
ActivateEngine();
int module1 = CreateModule();
int module2 = CreateModule();
...
DestroyModule(module2);
DestroyModule(module1);
TerminateEngine();
}
: 그 사용량이 뭔가를해야합니다.
Engine
개체는 싱글 톤으로 동작하며 ActivateEngine
및 TerminateEngine
에 바인딩됩니다.
Module
개체는 Engine
내에 많은 인스턴스를 만드는 데 사용되며 기본 API에서는 CreateModule
및 DestroyModule
에 바인딩됩니다.
가 발생했습니다 문제는
나는 (내가하지 [I 그리고 돈을 즉, 사용자가 Engine
에 대해 또는 객체의 수명에 대해 너무 많이 수행하지 않고 Modules
을 직접 만들 수있는 방식으로 일을 구현 한 '원하지 않음' 더 이상 사용하지 않을 경우 사용자가 객체를 폐기하도록합니다.
이렇게하려면 을 모두 가리키고 Engine
개체에 WeakReference
의 목록을 사용했습니다.
내 간단한 코드 here을 참조하십시오.
문제는 응용 프로그램의 종료, 종료 자 비 determistic 방법으로 전화를 WeakReference
목표는 Module
의 종결 자 아직 호출되지 않은 경우에도 이미 null이되어 때 매개 변수 trackResurrection
이 true로 설정되어 있다는 점이다. 내 경우
코드는 다음 로그 : 물론 부적절 순서입니다
ActivateEngine() ...
CreateModule() ==> 0 ...
CreateModule() ==> 1 ...
DestroyModule(1) ...
Ooops ... Can't dispose registered module because WeakReference to it is already null ...
Ooops ... Can't dispose registered module because WeakReference to it is already null ...
TerminateEngine() ...
DestroyModule(0) ...
합니다.
질문 모든 Module
을 강제 할 방법
는 Engine
전에 완료 할?
최종 사용자가 Module
개체에서 Dispose
메서드를 호출하도록 강요하고 싶지 않으며 코드에서 더 이상 참조되지 않을 때 개체가 자동으로 사라질 수 있도록 만든 Module
에 대한 강력한 참조를 유지하고 싶지 않습니다.예 : 나는 ConditionalWeakTable
을 사용하여 다음과 같은 스레드 보았다
processing
{
var module = new Module();
...
}
foo()
{
processing();
GC.Collect(); // If using strong references 'module' is gonna be kept alive (that's not smart)
}
:
- 이 C# WeakReference object is NULL in finalizer although still strongly referenced
- Get list of active items from ConditionalWeakTable
하지만이 내 상황에서 할 수있는 방법을 이해하지 않습니다.
는 엔진 싱글 및 모듈 객체 모두를 통해 엔진을 종료 할 의무를 배포 : 일반적인 문제에 대한 해결책보다는 특정 상황에 대한 해결 방법의
제공하신 간소화 된 [코드 링크] (https://gist.github.com/CitizenInsane/802bb4bd61c708f3402e)를 확인할 수 있습니까? – Rob
@Rob 죄송합니다. [다음] (https://gist.github.com/CitizenInsane/06d898e3e3c0a380d6a7) 링크를 수정했습니다. (새 링크로 질문이 수정되었습니다) – CitizenInsane
WeakReference가 어떻게 될지 잘 모릅니다. 유능한. 최소한 카운터 *, 간단한 정적 int가 필요합니다. 모든 CreateModule() 호출마다 증가시키고 모든 DetroyModule() 호출에 대해 감소시킵니다. 0에 도달하면 TerminateEngine()을 안전하게 호출 할 수 있습니다. –