C ++ / CX D'tor未调用

时间:2016-07-25 07:46:42

标签: c++ multithreading windows-runtime c++-cx circular-reference

我为WinRT应用程序创建了一个ref class Dispatcher,它使用来自Windows::System::Threading::ThreadPool的线程来创建一种消息泵基础结构。必须继承Dispatcher,以便派生类具有此机制。

问题是从这个基本Dispatcher派生的每个类都没有被破坏(不被称为)。

我解决了这个问题,我想我已经了解导致这个问题的原因,但我不知道如何解决这个问题。

以下是与此问题相关的一些代码:

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);
    }
};

所以,因为这是一个ref类,当引用计数达到0时应该调用它,但是因为我将this传递给WorkItemHandler委托,所以该线程持有对该引用的引用Dispatcher类,它导致循环引用。因此,由于线程无限期地等待设置m_invocationHandle事件,所以总是会引用this类,它永远不会调用它的析构函数(应该设置m_invocationHandle事件和等待线程完成。)

我考虑过使用Platform::WeakReference,但在调用Resolve之前,我必须Dispatcher^将其WaitForSingleObject(...)发送到m_invocationHandle才能获得user@host:/home/db2inst1:>db2 "select * from mytable" VAL NEW_VAL --- ------- 5 - 6 - A - 3 record(s) selected. user@host:/home/db2inst1:>db2 "CREATE VIEW MYTABLEVW AS SELECT NEW_VAL,VAL FROM MYTABLE" DB20000I The SQL command completed successfully. user@host:/home/db2inst1:>db2 "select * from mytablevw" NEW_VAL VAL ------- --- - 5 - 6 - A 3 record(s) selected. 这有助于提高引用次数。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

捕获"这个"如果您不想添加它,则作为常规指针而不是C ++ / CX指针。只需确保您的函数在析构函数完成之前结束:

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
    }
}