と呼ばれる私はメッセージポンプインフラのようなものを作成するためにWindows::System::Threading::ThreadPool
から糸を使用し、当社のWinRTのアプリケーション用にref class Dispatcher
を作成しました。 Dispatcher
は、このメカニズムを持つ派生クラスのために継承する必要があります。このベースディスパッチャから派生するすべてのクラスが破壊されていないことをC++/CX D'TORない
問題がある(D'のTORは呼び出されません)。
私はこの問題を分離し、私はこの問題を引き起こすものを理解していると思うが、私はこの問題を解決するかどうかはわかりません。
は、ここで問題に関連するコードの一部です:だから
public delegate void FunctionDelegate();
ref class Dispatcher
{
protected private:
Dispatcher()
{
m_invocationHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
m_disposed = false;
m_asyncThread = Windows::System::Threading::ThreadPool::RunAsync(
ref new Windows::System::Threading::WorkItemHandler(
[this](Windows::Foundation::IAsyncAction^ operation)
{
while (m_disposed == false)
{
WaitForSingleObject(m_invocationHandle, INFINITE);
//copy Pending Queue to Executing Queue
//Run all handlers in Executing Queue and clear it
}
}));
}
public:
virtual ~Dispatcher()
{
m_disposed = true;
SetEvent(m_invocationHandle);
JoinInvocationThread();
CleanUp(); //close handles etc...
}
void BeginInvoke(FunctionDelegate^ function)
{
PendingQueue->Append(function);
SetEvent(m_invocationHandle);
}
};
、これは参照クラスですので、参照カウントが0に達したときにそのドールのTorは呼び出される必要がありますが、私はthis
を渡すので、 WorkItemHandler
デリゲートの場合、スレッドはDispatcher
クラスへの参照を保持しており、循環参照が発生します。したがって、スレッドが無限にm_invocationHandle
イベントが設定されるのを待っていることから、(m_invocationHandle
イベントを設定し、スレッドが完了するのを待つ必要があります)そのデストラクタを呼び出すことはありませんthis
クラスへの参照が常にあります。
私はPlatform::WeakReference
を使用して考えたが、私はこれが同様に参照カウントが発生しますので、助けないm_invocationHandle
を得るためにWaitForSingleObject(...)
をcallsing前Dispatcher^
にResolve
にそれを持っています。
アイデア?あなたはそれが追加
@HansPassant ...これはC:ちょうどあなたの関数はデストラクタが終了する前に終了していることを確認してください'は完了しました – ZivS
2つのオブジェクトに分割します。 1つはパブリックDispatcherで、これは「実際の」ディスパッチャへの参照です。パブリックディスパッチャは破棄されると、「実際の」ディスパッチャにクリーンアップを指示します。 –
@RaymondChen、提案のおかげで、シンプルに聞こえて、私が望むカプセル化を維持します。私は実際には 'this'を渡すのではなく、必要なメンバーへの参照を渡すことでこれを解決しましたが、あなたの提案はよりクリーンに聞こえます。 – ZivS