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

Mik*_*ler 5 c++ asynchronous callback c++11

除了以下代码之外,还有哪些替代方案可以对对象执行安全的异步回调?

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;
};
Run Code Online (Sandbox Code Playgroud)

我想避免使用enable_shared_from_this(并避免客户m_service在非常常见的用例中需要它),但如果没有它,似乎很难延长MyClass回调中的一次的生命周期。

相反,在 lambda 中捕获this并尝试在 MyClass 的析构函数中取消注册它,或者阻止 MyClass 在回调完成之前被破坏,会导致竞争、死锁和失去简单性。我几乎可以肯定捕捉“这个”并不安全。

看来,如果 MyClass 要求 ashared_ptr<Service>回调它,它只能保证它保持有效,如果它可以管理或延长自己的生命周期(通过enable_shared_from_this),因为它不知道回调将持续多久。否则,无论谁拥有 ,或者谁知道 和 的生命周期,都必须有责任来MyClass处理这个问题,但这一切都变得非常容易出错且不切实际。ServiceMyClass

看来唯一可行的解​​决方案是:

  • enable_shared_from_this与“弱捕获”模式一起使用(如上面的代码)
  • 为 MyClass 提供 a ,Service&以便调用者有责任确保服务比它更长寿。
  • 使用静态方法/函数作为回调,并按值传递所需的所有内容(问题是有时您确实想将控制权传回,MyClass并且遇到相同的问题)。

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

Pup*_*ppy 1

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

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