C ++中安全异步回调的模式

时间:2015-02-02 10:03:51

标签: c++ c++11 asynchronous callback

对于在对象上执行安全异步回调,以下代码有哪些替代方法?

class MyClass : public std::enable_shared_from_this<MyClass>
{
private:

    void fetchResults()
    {
        std::weak_ptr<MyClass> weakSelf = shared_from_this();

        m_service.getResultAsync(
            /* args... */,
            /* Callback */
            [weakSelf](Result r)
            {
                auto self = weakSelf.lock();
                if (self)
                {
                    self->workFinishedWithResult(std::move(r));
                }
            });
    }

    void workFinishedWithResult(Result r) { // ... continue workflow }

    std::shared_ptr<Service> m_service;
};

我想避免使用enable_shared_from_this(并避免m_service的客户端要求它用于非常常见的用例),但似乎很难延长MyClass的生命周期一旦进入回调,没有它。

在lambda中捕获this,然后尝试在MyClass中取消注册{&#39}。析构函数,或阻止MyClass被破坏,直到回调完成是一个导致竞争,死锁和简单性的路径。我几乎肯定会抓住这个&#39;不能保证安全。

似乎MyClass要求shared_ptr<Service>回拨它,它只能保证它仍然有效,如果它可以管理或延长自己的生命周期(通过enable_shared_from_this),因为它没有&#39知道回调将持续多长时间。否则,它必须由拥有MyClass的任何人负责,或者知道ServiceMyClass的生命周期的人来处理这个问题,但这一切都变得非常容易出错,不切实际的。

似乎唯一可行的解​​决方案是:

  • 使用enable_shared_from_this与&#34;弱捕获&#34;模式(如上面的代码所示)
  • 让MyClass获得Service&,这样才能确保服务的使用时间超过调用者。
  • 使用静态方法/函数作为回调并按值传递所需的所有内容(问题是有时您确实希望将控制权传递回MyClass并且您遇到同样的问题)。

这里有哪些替代方案?或者在执行异步C ++时使用enable_shared_from_this是不可避免的?

1 个答案:

答案 0 :(得分:1)

您正在寻找的确切事项是std::future<T>::then()。它在C ++ 11中不存在,但是boost :: future提供它。

但是,在一般情况下,调用者有责任确保服务和MyClass实例的存活时间足够长,尽管如果该方法采用对服务的拥有引用也是可以接受的。