public static int updateTable(string table, Hashtable hashtable, string where, string database) { string sql = "UPDATE " + table + " SET "; string val = ""; DateTime dt = DateTime.Now; IDictionaryEnumerator en = hashtable.GetEnumerator(); while (en.MoveNext()) { if (en.Value != null) { if (en.Key.ToString() != "ID") { string value = en.Value.ToString(); string typeName = en.GetType().Name; // liar if (en.Value.GetType() == dt.GetType()) { value = new SqlDateTime((DateTime)en.Value).ToSqlString().ToString(); } if (en.Value.GetType() == value.GetType() || en.Value.GetType() == dt.GetType()) // if its a string or datatime add quotes { val = " '" + value + "' "; } else { if (value.ToLower().Contains("false")) { value = "0"; } if (value.ToLower().Contains("true")) { value = "1"; } val = " " + value + " "; } sql += "[" + en.Key + "]" + " = " + val + ","; } } } if (sql.Length > 0) { if (sql[sql.Length - 1] == ',') { sql = sql.Substring(0, sql.Length - 1); } } sql += where; return(nonQuery(sql, database)); }
// remove dead entries. When purgeAll is true, remove all entries. private bool Purge(bool purgeAll) { bool foundDirt = false; using (this.WriteLock) { #if WeakEventTelemetry WeakEventLogger.LogSnapshot(this, "+Purge"); #endif if (!BaseAppContextSwitches.EnableWeakEventMemoryImprovements) { // copy the keys into a separate array, so that later on // we can change the table while iterating over the keys ICollection ic = _dataTable.Keys; EventKey[] keys = new EventKey[ic.Count]; ic.CopyTo(keys, 0); for (int i = keys.Length - 1; i >= 0; --i) { object data = _dataTable[keys[i]]; // a purge earlier in the loop may have removed keys[i], // in which case there's nothing more to do if (data != null) { object source = keys[i].Source; foundDirt |= keys[i].Manager.PurgeInternal(source, data, purgeAll); // if source has been GC'd, remove its data if (!purgeAll && source == null) { _dataTable.Remove(keys[i]); } } } #if WeakEventTelemetry LogAllocation(ic.GetType(), 1, 12); // _dataTable.Keys - Hashtable+KeyCollection LogAllocation(typeof(EventKey[]), 1, 12 + ic.Count * 12); // keys LogAllocation(typeof(EventKey), ic.Count, 8 + 12); // box(key) LogAllocation(typeof(ReaderWriterLockWrapper), 1, 12); // actually the RWLW+AutoWriterRelease from WriteLock LogAllocation(typeof(Action), 2, 32); // anonymous delegates in RWLW #endif } else { Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty"); _inPurge = true; // enumerate the dictionary using IDE explicitly rather than // foreach, to avoid allocating temporary DictionaryEntry objects IDictionaryEnumerator ide = _dataTable.GetEnumerator() as IDictionaryEnumerator; while (ide.MoveNext()) { EventKey key = (EventKey)ide.Key; object source = key.Source; foundDirt |= key.Manager.PurgeInternal(source, ide.Value, purgeAll); // if source has been GC'd, remove its data if (!purgeAll && source == null) { _toRemove.Add(key); } } #if WeakEventTelemetry LogAllocation(ide.GetType(), 1, 36); // Hashtable+HashtableEnumerator #endif _inPurge = false; } if (purgeAll) { _managerTable.Clear(); _dataTable.Clear(); } else if (_toRemove.Count > 0) { foreach (EventKey key in _toRemove) { _dataTable.Remove(key); } _toRemove.Clear(); _toRemove.TrimExcess(); } #if WeakEventTelemetry ++_purgeCount; if (!foundDirt) { ++_purgeNoops; } WeakEventLogger.LogSnapshot(this, "-Purge"); #endif } return(foundDirt); }
public bool Purge(bool purgeAll) { bool foundDirt = false; if (!purgeAll) { if (!MS.Internal.BaseAppContextSwitches.EnableWeakEventMemoryImprovements) { // copy the keys into a separate array, so that later on // we can change the dictionary while iterating over the keys ICollection ic = _dict.Keys; String[] keys = new String[ic.Count]; ic.CopyTo(keys, 0); for (int i = keys.Length - 1; i >= 0; --i) { if (keys[i] == AllListenersKey) { continue; // ignore the special entry for now } // for each key, remove dead entries in its list PropertyRecord pr = (PropertyRecord)_dict[keys[i]]; if (pr.Purge()) { foundDirt = true; } // if there are no more entries, remove the key if (pr.IsEmpty) { pr.StopListening(_type); _dict.Remove(keys[i]); } } #if WeakEventTelemetry _manager.LogAllocationRelay(ic.GetType(), 1, 12); // dict.Keys - Hashtable+KeyCollection _manager.LogAllocationRelay(typeof(String[]), 1, 12 + ic.Count * 4); // keys #endif } else { Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty"); // enumerate the dictionary using IDE explicitly rather than // foreach, to avoid allocating temporary DictionaryEntry objects IDictionaryEnumerator ide = _dict.GetEnumerator() as IDictionaryEnumerator; while (ide.MoveNext()) { String key = (String)ide.Key; if (key == AllListenersKey) { continue; // ignore the special entry for now } // for each key, remove dead entries in its list PropertyRecord pr = (PropertyRecord)ide.Value; if (pr.Purge()) { foundDirt = true; } // if there are no more entries, remove the key if (pr.IsEmpty) { pr.StopListening(_type); _toRemove.Add(key); } } // do the actual removal (outside the dictionary iteration) if (_toRemove.Count > 0) { foreach (String key in _toRemove) { _dict.Remove(key); } _toRemove.Clear(); _toRemove.TrimExcess(); } #if WeakEventTelemetry Type enumeratorType = ide.GetType(); if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0) { _manager.LogAllocationRelay(enumeratorType, 1, 24); // ListDictionary+NodeEnumerator } else { _manager.LogAllocationRelay(enumeratorType, 1, 36); // Hashtable+HashtableEnumerator } #endif } if (foundDirt) { // if any entries were purged, invalidate the special entry _dict.Remove(AllListenersKey); _proposedAllListenersList = null; } if (IsEmpty) { StopListening(); } } else { // stop listening. List cleanup is handled by Purge() foundDirt = true; StopListening(); foreach (DictionaryEntry de in _dict) { PropertyRecord pr = (PropertyRecord)de.Value; pr.StopListening(_type); } } return(foundDirt); }
/// <summary> /// Remove dead entries from the data for the given source. Returns true if /// some entries were actually removed. /// </summary> protected override bool Purge(object source, object data, bool purgeAll) { bool foundDirt = false; if (!purgeAll) { HybridDictionary dict = (HybridDictionary)data; int ignoredKeys = 0; if (!BaseAppContextSwitches.EnableWeakEventMemoryImprovements) { // copy the keys into a separate array, so that later on // we can change the dictionary while iterating over the keys ICollection ic = dict.Keys; String[] keys = new String[ic.Count]; ic.CopyTo(keys, 0); for (int i = keys.Length - 1; i >= 0; --i) { if (keys[i] == AllListenersKey) { ++ignoredKeys; continue; // ignore the special entry for now } // for each key, remove dead entries in its list bool removeList = purgeAll || source == null; if (!removeList) { ListenerList list = (ListenerList)dict[keys[i]]; if (ListenerList.PrepareForWriting(ref list)) { dict[keys[i]] = list; } if (list.Purge()) { foundDirt = true; } removeList = (list.IsEmpty); } // if there are no more entries, remove the key if (removeList) { dict.Remove(keys[i]); } } #if WeakEventTelemetry LogAllocation(ic.GetType(), 1, 12); // dict.Keys - Hashtable+KeyCollection LogAllocation(typeof(String[]), 1, 12 + ic.Count * 4); // keys #endif } else { Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty"); // If an "in-use" list is changed, we will re-install its clone // back into the dictionary. Doing this inside the loop // causes an exception "collection was modified after the enumerator // was instantiated" (DDVSO 812614), so instead just record // what to do and do the actual work after the loop. // This is a rare case - it only arises if a PropertyChanged event // handler calls (indirectly) into the cleanup code - so allocate // the temporary memory lazily on the stack. // [In the bug, the indirect call comes about because the app's // event handler calls ShowDialog(), which pushes a dispatcher // frame to run a nested message pump. Then a pending cleanup task // reaches the front of the dispatcher queue before the dialog // is dismissed, effectively calling this method while the // PropertyChanged event delivery is in progress.] HybridDictionary toInstall = null; // enumerate the dictionary using IDE explicitly rather than // foreach, to avoid allocating temporary DictionaryEntry objects IDictionaryEnumerator ide = dict.GetEnumerator() as IDictionaryEnumerator; while (ide.MoveNext()) { String key = (String)ide.Key; if (key == AllListenersKey) { ++ignoredKeys; continue; // ignore the special entry for now } // for each key, remove dead entries in its list bool removeList = purgeAll || source == null; if (!removeList) { ListenerList list = (ListenerList)ide.Value; bool inUse = ListenerList.PrepareForWriting(ref list); bool isChanged = false; if (list.Purge()) { isChanged = true; foundDirt = true; } removeList = (list.IsEmpty); // if a cloned list changed, remember the details // so that the clone can be installed back into the // dictionary outside the iteration (DDVSO 812614) if (!removeList && inUse && isChanged) { if (toInstall == null) { // lazy allocation toInstall = new HybridDictionary(); } toInstall[key] = list; } } // if there are no more entries, remove the key if (removeList) { _toRemove.Add(key); } } // do the actual removal (outside the dictionary iteration) if (_toRemove.Count > 0) { foreach (String key in _toRemove) { dict.Remove(key); } _toRemove.Clear(); _toRemove.TrimExcess(); } // do the actual re-install of "in-use" lists that changed if (toInstall != null) { IDictionaryEnumerator installDE = toInstall.GetEnumerator() as IDictionaryEnumerator; while (installDE.MoveNext()) { String key = (String)installDE.Key; ListenerList list = (ListenerList)installDE.Value; dict[key] = list; } } #if WeakEventTelemetry Type enumeratorType = ide.GetType(); if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0) { LogAllocation(enumeratorType, 1, 24); // ListDictionary+NodeEnumerator } else { LogAllocation(enumeratorType, 1, 36); // Hashtable+HashtableEnumerator } #endif } if (dict.Count == ignoredKeys) { // if there are no more listeners at all, remove the entry from // the main table, and prepare to stop listening purgeAll = true; if (source != null) // source may have been GC'd { this.Remove(source); } } else if (foundDirt) { // if any entries were purged, invalidate the special entry dict.Remove(AllListenersKey); _proposedAllListenersList = null; } } if (purgeAll) { // stop listening. List cleanup is handled by Purge() if (source != null) // source may have been GC'd { StopListening(source); } foundDirt = true; } return(foundDirt); }
/// <summary> /// Remove dead entries from the data for the given source. Returns true if /// some entries were actually removed. /// </summary> protected override bool Purge(object source, object data, bool purgeAll) { bool foundDirt = false; HybridDictionary dict = (HybridDictionary)data; if (!MS.Internal.BaseAppContextSwitches.EnableWeakEventMemoryImprovements) { // copy the keys into a separate array, so that later on // we can change the dictionary while iterating over the keys ICollection ic = dict.Keys; PropertyDescriptor[] keys = new PropertyDescriptor[ic.Count]; ic.CopyTo(keys, 0); for (int i = keys.Length - 1; i >= 0; --i) { // for each key, remove dead entries in its list bool removeList = purgeAll || source == null; ValueChangedRecord record = (ValueChangedRecord)dict[keys[i]]; if (!removeList) { if (record.Purge()) { foundDirt = true; } removeList = record.IsEmpty; } // if there are no more entries, remove the key if (removeList) { record.StopListening(); if (!purgeAll) { dict.Remove(keys[i]); } } } #if WeakEventTelemetry LogAllocation(ic.GetType(), 1, 12); // dict.Keys - Hashtable+KeyCollection LogAllocation(typeof(String[]), 1, 12 + ic.Count * 4); // keys #endif } else { Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty"); // enumerate the dictionary using IDE explicitly rather than // foreach, to avoid allocating temporary DictionaryEntry objects IDictionaryEnumerator ide = dict.GetEnumerator() as IDictionaryEnumerator; while (ide.MoveNext()) { // for each key, remove dead entries in its list bool removeList = purgeAll || source == null; ValueChangedRecord record = (ValueChangedRecord)ide.Value; if (!removeList) { if (record.Purge()) { foundDirt = true; } removeList = record.IsEmpty; } // if there are no more entries, remove the key if (removeList) { record.StopListening(); if (!purgeAll) { _toRemove.Add((PropertyDescriptor)ide.Key); } } } // do the actual removal (outside the dictionary iteration) if (_toRemove.Count > 0) { foreach (PropertyDescriptor key in _toRemove) { dict.Remove(key); } _toRemove.Clear(); _toRemove.TrimExcess(); } #if WeakEventTelemetry Type enumeratorType = ide.GetType(); if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0) { LogAllocation(enumeratorType, 1, 24); // ListDictionary+NodeEnumerator } else { LogAllocation(enumeratorType, 1, 36); // Hashtable+HashtableEnumerator } #endif } // if there are no more listeners at all, remove the entry from // the main table if (dict.Count == 0) { foundDirt = true; if (source != null) // source may have been GC'd { this.Remove(source); } } return(foundDirt); }
/// <summary> /// Remove dead entries from the data for the given source. Returns true if /// some entries were actually removed. /// </summary> protected override bool Purge(object source, object data, bool purgeAll) { bool foundDirt = false; if (!purgeAll) { HybridDictionary dict = (HybridDictionary)data; int ignoredKeys = 0; if (!BaseAppContextSwitches.EnableWeakEventMemoryImprovements) { // copy the keys into a separate array, so that later on // we can change the dictionary while iterating over the keys ICollection ic = dict.Keys; String[] keys = new String[ic.Count]; ic.CopyTo(keys, 0); for (int i = keys.Length - 1; i >= 0; --i) { if (keys[i] == AllListenersKey) { ++ignoredKeys; continue; // ignore the special entry for now } // for each key, remove dead entries in its list bool removeList = purgeAll || source == null; if (!removeList) { ListenerList list = (ListenerList)dict[keys[i]]; if (ListenerList.PrepareForWriting(ref list)) { dict[keys[i]] = list; } if (list.Purge()) { foundDirt = true; } removeList = (list.IsEmpty); } // if there are no more entries, remove the key if (removeList) { dict.Remove(keys[i]); } } #if WeakEventTelemetry LogAllocation(ic.GetType(), 1, 12); // dict.Keys - Hashtable+KeyCollection LogAllocation(typeof(String[]), 1, 12 + ic.Count * 4); // keys #endif } else { Debug.Assert(_toRemove.Count == 0, "to-remove list should be empty"); // enumerate the dictionary using IDE explicitly rather than // foreach, to avoid allocating temporary DictionaryEntry objects IDictionaryEnumerator ide = dict.GetEnumerator() as IDictionaryEnumerator; while (ide.MoveNext()) { String key = (String)ide.Key; if (key == AllListenersKey) { ++ignoredKeys; continue; // ignore the special entry for now } // for each key, remove dead entries in its list bool removeList = purgeAll || source == null; if (!removeList) { ListenerList list = (ListenerList)ide.Value; if (ListenerList.PrepareForWriting(ref list)) { dict[key] = list; } if (list.Purge()) { foundDirt = true; } removeList = (list.IsEmpty); } // if there are no more entries, remove the key if (removeList) { _toRemove.Add(key); } } // do the actual removal (outside the dictionary iteration) if (_toRemove.Count > 0) { foreach (String key in _toRemove) { dict.Remove(key); } _toRemove.Clear(); _toRemove.TrimExcess(); } #if WeakEventTelemetry Type enumeratorType = ide.GetType(); if (enumeratorType.Name.IndexOf("NodeEnumerator") >= 0) { LogAllocation(enumeratorType, 1, 24); // ListDictionary+NodeEnumerator } else { LogAllocation(enumeratorType, 1, 36); // Hashtable+HashtableEnumerator } #endif } if (dict.Count == ignoredKeys) { // if there are no more listeners at all, remove the entry from // the main table, and prepare to stop listening purgeAll = true; if (source != null) // source may have been GC'd { this.Remove(source); } } else if (foundDirt) { // if any entries were purged, invalidate the special entry dict.Remove(AllListenersKey); _proposedAllListenersList = null; } } if (purgeAll) { // stop listening. List cleanup is handled by Purge() if (source != null) // source may have been GC'd { StopListening(source); } foundDirt = true; } return(foundDirt); }