意外行为在lambda中传递弱引用

时间:2017-05-07 17:41:09

标签: asynchronous lambda weak-references c++-cx

如果我使用此代码,该函数会返回null,因为Resolve有时会工作并且有时会失败(基于调用它的时间)

 Platform::WeakReference wr(this);
 Windows::Foundation::Collections::IAsyncOperation<Object1^>^ asyncTask = 
    concurrency::create_async(
    [wr, timeoutMS](concurrency::cancellation_token token) -> Object1^
    {
       if (auto refToThis = wr.Resolve<CurrentClass>())
       {
         // Do something
       }
       else return null; // The code took this path if the call was made 
                         // immediately, if the call was made from inner 
                         // page or 
                         // even after 5 sec in Main Page init – It always 
                         // worked
    }

如果我在lambda表达式中传递此引用,它总是会解析

 Platform::WeakReference wr(this);
 Windows::Foundation::Collections::IAsyncOperation<Object1^>^ asyncTask = 
    concurrency::create_async(
    [this, wr, timeoutMS](concurrency::cancellation_token token) -> Object1^
    {
       if (auto refToThis = wr.Resolve<CurrentClass>())
       {
         // Do something - It resolves always now
       }
       else return null; 
    }

有什么理由发生这种情况?我是C ++ / Cx的新手,我读到在lambda表达式中传递这个ref并不好,但如果我没有通过则解析失败

1 个答案:

答案 0 :(得分:0)

为什么第二个示例始终有效:

  • 您正在lambda闭包[]中捕获this,意味着您正在lambda范围内执行this的副本。由于这可能是ref class,这意味着你在它上面增加指针的引用计数器,这意味着它不会被销毁。在解析弱引用时,由于this仍然存在,您可以从弱引用中检索它。

  • 在第一个示例中,您只传递对lambda闭包的弱引用,因为您可能正在使用某个UI元素,如果它被销毁,弱引用解析将返回nullptr

你应该在lambda闭包中传递一个弱引用或直接this,但是如果你传递this,你应该确保你将被这个lambda调用以避免保持对象的引用,导致它永远不会被删除,造成内存泄漏。