// This method is called upon Execute of a command associated with a SqlDependency object. internal string AddCommandEntry(string commandHash, SqlDependency dep) { string notificationId = string.Empty; lock (_instanceLock) { if (_dependencyIdToDependencyHash.ContainsKey(dep.Id)) { // check if we already have notification associated with given command hash if (_commandHashToNotificationId.TryGetValue(commandHash, out notificationId)) { // we have one or more SqlDependency instances with same command hash DependencyList dependencyList = null; if (!_notificationIdToDependenciesHash.TryGetValue(notificationId, out dependencyList)) { // this should not happen since _commandHashToNotificationId and _notificationIdToDependenciesHash are always // updated together Debug.Fail("_commandHashToNotificationId has entries that were removed from _notificationIdToDependenciesHash. Remember to keep them in sync"); throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyCommandHashIsNotAssociatedWithNotification); } // join the new dependency to the list if (!dependencyList.Contains(dep)) { dependencyList.Add(dep); } } else { // we did not find notification ID with the same app domain and command hash, create a new one // use unique guid to avoid duplicate IDs // prepend app domain ID to the key - SqlConnectionContainer::ProcessNotificationResults (SqlDependencyListener.cs) // uses this app domain ID to route the message back to the app domain in which this SqlDependency was created notificationId = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0};{1}", SqlDependency.AppDomainKey, // must be first Guid.NewGuid().ToString("D", System.Globalization.CultureInfo.InvariantCulture) ); DependencyList dependencyList = new DependencyList(commandHash); dependencyList.Add(dep); // map command hash to notification we just created to reuse it for the next client _commandHashToNotificationId.Add(commandHash, notificationId); _notificationIdToDependenciesHash.Add(notificationId, dependencyList); } Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in sync!"); } } return(notificationId); }
internal string AddCommandEntry(string commandHash, SqlDependency dep) { IntPtr ptr; string str = string.Empty; Bid.NotificationsScopeEnter(out ptr, "<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> %d#, commandHash: '%ls', SqlDependency: %d#", this.ObjectID, commandHash, dep.ObjectID); try { lock (this) { if (!this._dependencyIdToDependencyHash.ContainsKey(dep.Id)) { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Dependency not present in depId->dep hash, must have been invalidated.\n"); return(str); } if (this._commandHashToNotificationId.TryGetValue(commandHash, out str)) { DependencyList list2 = null; if (!this._notificationIdToDependenciesHash.TryGetValue(str, out list2)) { throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyCommandHashIsNotAssociatedWithNotification); } if (!list2.Contains(dep)) { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Dependency not present for commandHash, adding.\n"); list2.Add(dep); return(str); } Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Dependency already present for commandHash.\n"); return(str); } str = string.Format(CultureInfo.InvariantCulture, "{0};{1}", new object[] { SqlDependency.AppDomainKey, Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture) }); Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Creating new Dependencies list for commandHash.\n"); DependencyList list = new DependencyList(commandHash) { dep }; try { } finally { this._commandHashToNotificationId.Add(commandHash, str); this._notificationIdToDependenciesHash.Add(str, list); } return(str); } } finally { Bid.ScopeLeave(ref ptr); } return(str); }
// This method is called upon Execute of a command associated with a SqlDependency object. internal string AddCommandEntry(string commandHash, SqlDependency dep) { IntPtr hscp; string notificationId = string.Empty; Bid.NotificationsScopeEnter(out hscp, "<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> %d#, commandHash: '%ls', SqlDependency: %d#", ObjectID, commandHash, dep.ObjectID); try { lock (this) { if (!_dependencyIdToDependencyHash.ContainsKey(dep.Id)) // Determine if depId->dep hashtable contains dependency. If not, it's been invalidated. { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Dependency not present in depId->dep hash, must have been invalidated.\n"); } else { // check if we already have notification associated with given command hash if (_commandHashToNotificationId.TryGetValue(commandHash, out notificationId)) { // we have one or more SqlDependency instances with same command hash DependencyList dependencyList = null; if (!_notificationIdToDependenciesHash.TryGetValue(notificationId, out dependencyList)) { // this should not happen since _commandHashToNotificationId and _notificationIdToDependenciesHash are always // updated together Debug.Assert(false, "_commandHashToNotificationId has entries that were removed from _notificationIdToDependenciesHash. Remember to keep them in [....]"); throw ADP.InternalError(ADP.InternalErrorCode.SqlDependencyCommandHashIsNotAssociatedWithNotification); } // join the new dependency to the list if (!dependencyList.Contains(dep)) { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Dependency not present for commandHash, adding.\n"); dependencyList.Add(dep); } else { Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Dependency already present for commandHash.\n"); } } else { // we did not find notification ID with the same app domain and command hash, create a new one // use unique guid to avoid duplicate IDs // prepend app domain ID to the key - SqlConnectionContainer::ProcessNotificationResults (SqlDependencyListener.cs) // uses this app domain ID to route the message back to the app domain in which this SqlDependency was created notificationId = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0};{1}", SqlDependency.AppDomainKey, // must be first Guid.NewGuid().ToString("D", System.Globalization.CultureInfo.InvariantCulture) ); Bid.NotificationsTrace("<sc.SqlDependencyPerAppDomainDispatcher.AddCommandEntry|DEP> Creating new Dependencies list for commandHash.\n"); DependencyList dependencyList = new DependencyList(commandHash); dependencyList.Add(dep); // map command hash to notification we just created to reuse it for the next client // do it inside finally block to avoid ThreadAbort exception interrupt this operation try {} finally { _commandHashToNotificationId.Add(commandHash, notificationId); _notificationIdToDependenciesHash.Add(notificationId, dependencyList); } } Debug.Assert(_notificationIdToDependenciesHash.Count == _commandHashToNotificationId.Count, "always keep these maps in [....]!"); } } } finally { Bid.ScopeLeave(ref hscp); } return(notificationId); }