在下面的示例中,对HandleChangesAsync的调用是在异步任务中通过事件处理程序进行的。
我担心有一个潜在的竞争条件,其中一个线程正在HandleChangesAsync中执行create_task块。当发生这种情况时,OnSomethingChanged处理程序触发,第二个线程最终在HandleChangesAsync中执行相同的create_task块,
问题 - 假设这种担忧是合法的,那么消除这种竞争条件的正确方法是什么?
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())
.then([weakThis]())
{
// do stuff
});
}
答案 0 :(得分:0)
避免竞争条件的一种简单方法是将您正在创建的任务链接到HandleChangesAsync
,这样您就可以确定它们将一个接一个地执行。
为此,您需要在班级中添加新成员,例如
task<void> _handleChangesAsyncTask;
std::mutex _lock;
然后HandleChangesAsync
中的代码变为:
void MyClass::HandleChangesAsync()
{
std::lock_guard<std::mutex> lk(_lock);
WeakReference weakThis(this);
handleChangesAsyncTask = handleChangesAsyncTask.then(
[]()
{
return create_task(DoMoreCoolStuffAsync());
}).then(
[weakThis]()
{
// do stuff
});
}
注意互斥锁以防止对_handleChangesAsyncTask
的并发访问。