private void PopScope()
{
bool shouldRestoreContextData = true;
// Clear the current TransactionScope CallContext data
if (AsyncFlowEnabled)
{
CallContextCurrentData.ClearCurrentData(ContextKey, true);
}
if (_scopeThread == Thread.CurrentThread)
{
// async function yield at await points and main thread can continue execution. We need to make sure the TLS data are restored appropriately.
// Restore the TLS only if the thread Ids match.
RestoreSavedTLSContextData();
}
// Restore threadContextData to parent CallContext or TLS data
if (_savedCurrentScope != null)
{
if (_savedCurrentScope.AsyncFlowEnabled)
{
_threadContextData = CallContextCurrentData.CreateOrGetCurrentData(_savedCurrentScope.ContextKey);
}
else
{
if (_savedCurrentScope._scopeThread != Thread.CurrentThread)
{
// Clear TLS data so that transaction doesn't leak from current thread.
shouldRestoreContextData = false;
ContextData.TLSCurrentData = null;
}
else
{
_threadContextData = ContextData.TLSCurrentData;
}
CallContextCurrentData.ClearCurrentData(_savedCurrentScope.ContextKey, false);
}
}
else
{
// No parent TransactionScope present
// Clear any CallContext data
CallContextCurrentData.ClearCurrentData(null, false);
if (_scopeThread != Thread.CurrentThread)
{
// Clear TLS data so that transaction doesn't leak from current thread.
shouldRestoreContextData = false;
ContextData.TLSCurrentData = null;
}
else
{
// Restore the current data to TLS.
ContextData.TLSCurrentData = _threadContextData;
}
}
// prevent restoring the context in an unexpected thread due to thread switch during TransactionScope's Dispose
if (shouldRestoreContextData)
{
_threadContextData.CurrentScope = _savedCurrentScope;
RestoreCurrent();
}
}