1

と呼ばれる私はメッセージポンプインフラのようなものを作成するために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にそれを持っています。

アイデア?あなたはそれが追加

+0

@HansPassant ...これはC:ちょうどあなたの関数はデストラクタが終了する前に終了していることを確認してください'は完了しました – ZivS

+0

2つのオブジェクトに分割します。 1つはパブリックDispatcherで、これは「実際の」ディスパッチャへの参照です。パブリックディスパッチャは破棄されると、「実際の」ディスパッチャにクリーンアップを指示します。 –

+0

@RaymondChen、提案のおかげで、シンプルに聞こえて、私が望むカプセル化を維持します。私は実際には 'this'を渡すのではなく、必要なメンバーへの参照を渡すことでこれを解決しましたが、あなたの提案はよりクリーンに聞こえます。 – ZivS

答えて

0

キャプチャではなくC++/CXポインタよりも「この」として定期的にポインタをしたくない場合。私はあなたがc'torは非同期に実行されるスレッドプールからのスレッドを作成しているという事実が欠けていると思う

Dispatcher() 
{ 
    m_invocationHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr); 
    m_disposed = false; 
    IInspectable* _this = reinterpret_cast<IInspectable*>(this); 

    m_asyncThread = Windows::System::Threading::ThreadPool::RunAsync(
     ref new Windows::System::Threading::WorkItemHandler(
      [_this](Windows::Foundation::IAsyncAction^ operation) 
    { 
      reinterpret_cast<Dispatcher^>(_this)->MyLoop(); 
    })); 
} 

void MyLoop() 
{ 
    while (m_disposed == false) 
    { 
     WaitForSingleObject(m_invocationHandle, INFINITE); 
     //copy Pending Queue to Executing Queue 
     //Run all handlers in Executing Queue and clear it 
    } 
} 
+1

ラムダは破壊すると 'this'をリリースし、今はダブルリリースのバグがあります。 –

+0

あなたは正しいです。一定。 – Sunius

関連する問題