【发布时间】:2018-10-02 07:15:44
【问题描述】:
在下面的示例中,对 HandleChangesAsync 的调用是从异步任务中并通过事件处理程序进行的。
问题 - 有没有办法确保一次只有一个线程可以执行 HandleChangesAsync create_task + 任务继续块(即使任务继续块调用其他异步函数)?
请注意,我不能只使用同步原语,因为 HandleChangesAsync 可以在异步操作完成之前返回。
void MyClass::DoStuffAsync()
{
WeakReference weakThis(this);
create_task(DoMoreStuffAsync())
.then([weakThis]())
{
auto strongThis = weakThis.Resolve<HomePromotionTemplateViewModel>();
if (strongThis)
{
strongThis->RegisterForChanges();
strongThis->HandleChangesAsync();
}
});
}
void MyClass::RegisterForChanges()
{
// Attach event handler to &MyClass::OnSomethingChanged
}
void MyClass::OnSomethingChanged()
{
HandleChangesAsync();
}
void MyClass::HandleChangesAsync()
{
WeakReference weakThis(this);
create_task(DoMoreCoolStuffAsync(m_needsProtection))
.then([weakThis]()
{
// do async stuff
// update m_needsProtection
})
.then([weakThis]()
{
// do more async stuff
// update m_needsProtection
});
}
【问题讨论】:
-
与其尝试在许多异步操作中兼顾线程保护,不如在需要同步的数据周围放置一个互斥锁?
-
@vu1p3n0x - 我已经调整了代码示例。 1)我真的想知道在这种情况下是否可以进行线程同步。 2)如果我确实使用了互斥锁,我该如何在上面的代码示例中实际调用锁呢?
-
一目了然,代码要达到什么目的并不清楚。 X是什么? en.wikipedia.org/wiki/XY_problem 不管是什么,我怀疑有一个更简单的解决方案。
-
@JiveDadson - 我只是想了解是否可以通过 create_task 和延续来同步执行异步操作的代码块(在本例中为 HandleChangesAsync() 的主体)。如果所有操作都是同步的,我会用锁包围它们并完成。但这不是异步的选项,所以我想知道是否有替代方案。
-
我的问题是你为什么要这样做?您要解决的根本问题是什么?