Let's say I have a ViewModel that can be destroyed when a user navigates away from its bound View. The destructor performs cleanup on a subscription member variable:
MyViewModel::~MyViewModel()
{
if (m_subscription)
{
if (m_contentChangedToken.Value != 0)
{
m_subscription->ContentChanged -= m_contentChangedToken;
m_contentChangedToken.Value = 0;
}
}
}
After the ViewModel is created, a function runs which asynchronously gets the subscription, assigns it to a member variable, and assigns event listeners
void MyViewModel::AwesomeFunctionAsync()
{
create_task(TargetedContentSubscription::GetAsync(c_subId))
.then([this](TargetedContentSubscription^ subscription)
{
if (subscription)
{
m_subscription = subscription;
m_contentChangedToken = m_subscription->ContentChanged += // attach event
}
}, task_continuation_context::use_arbitrary());
}
Now let's say my ViewModel is being destroyed while a background thread is running code inside AwesomeFunctionAsync. Is there a race condition lurking here? For instance, might the destructor run before the event is attached by the background thread? Or can I trust the destructor is always last due to the GC?