// both receive and send initialize correlations using this method // if selectHandle is not null, we first try to initalize instanceKey with it , else we try to initalize the ambient handle // if ambient handle is not used for initializing instance key , we might use it for initalizing queryCorrelationsInitalizer. // SelectHandle usage: // Receive: selectHandle is the correlatesWith handle // SendReply: in case of context based correlation, this is the context handle // Send: in case of context based correlation, this will be the callback handle // ReceiveReply: selectHandle will be always null // Note that only Receive can initialize a content based correlation with a selectHandle (parallel convoy) internal static void InitializeCorrelationHandles(NativeActivityContext context, CorrelationHandle selectHandle, CorrelationHandle ambientHandle, Collection <CorrelationInitializer> additionalCorrelations, InstanceKey instanceKey, ICollection <InstanceKey> additionalKeys) { bool isAmbientHandleUsed = false; if (instanceKey != null && instanceKey.IsValid) { if (selectHandle != null) { selectHandle.InitializeBookmarkScope(context, instanceKey); } else if (ambientHandle != null) { ambientHandle.InitializeBookmarkScope(context, instanceKey); isAmbientHandleUsed = true; } else if (context.DefaultBookmarkScope.IsInitialized) { if (context.DefaultBookmarkScope.Id != instanceKey.Value) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR2.CorrelationHandleInUse(context.DefaultBookmarkScope.Id, instanceKey.Value))); } } else { context.DefaultBookmarkScope.Initialize(context, instanceKey.Value); } } if (additionalKeys != null && additionalCorrelations != null) { // The ordering of items in SelectAdditional and additional correlations are the same // Therefore, we assign keys iteratively IEnumerator <CorrelationInitializer> enumerator = additionalCorrelations.GetEnumerator(); foreach (InstanceKey key in additionalKeys) { Fx.Assert(key != null && key.IsValid, "only valid keys should be passed into InitializeCorrelationHandles"); while (enumerator.MoveNext()) { QueryCorrelationInitializer queryCorrelation = enumerator.Current as QueryCorrelationInitializer; if (queryCorrelation != null) { CorrelationHandle handle = (queryCorrelation.CorrelationHandle != null ? queryCorrelation.CorrelationHandle.Get(context) : null); if (handle == null) { if (ambientHandle != null && !isAmbientHandleUsed) { handle = ambientHandle; isAmbientHandleUsed = true; } else { throw FxTrace.Exception.AsError( new InvalidOperationException(SR2.QueryCorrelationInitializerCannotBeInitialized)); } } handle.InitializeBookmarkScope(context, key); break; } } } } }