예제 #1
0
        // 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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        // 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);
        }