private static void WeakKey() { var people = new[] { new Person {Id = 1, Name = "Jurian Naul" }, new Person {Id = 2, Name = "Thomas Bent" }, new Person {Id = 3, Name = "Ellen Carson" }, new Person {Id = 4, Name = "Katrina Lauran" }, new Person {Id = 5, Name = "Monica Ausbach" }, }; var locations = new ConditionalWeakTable<Person, string>(); locations.Add(people[0], "Shinon"); locations.Add(people[1], "Lance"); locations.Add(people[2], "Pidona"); locations.Add(people[3], "Loanne"); locations.Add(people[4], "Loanne"); foreach (var p in people) { string location; if (locations.TryGetValue(p, out location)) Console.WriteLine(p.Name + " at " + location); } }
public static void InvalidArgs_Throws() { var cwt = new ConditionalWeakTable<object, object>(); object ignored; Assert.Throws<ArgumentNullException>("key", () => cwt.Add(null, new object())); // null key Assert.Throws<ArgumentNullException>("key", () => cwt.TryGetValue(null, out ignored)); // null key Assert.Throws<ArgumentNullException>("key", () => cwt.Remove(null)); // null key Assert.Throws<ArgumentNullException>("createValueCallback", () => cwt.GetValue(new object(), null)); // null delegate object key = new object(); cwt.Add(key, key); Assert.Throws<ArgumentException>(null, () => cwt.Add(key, key)); // duplicate key }
public static void AddMany_ThenRemoveAll(int numObjects) { object[] keys = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); object[] values = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); var cwt = new ConditionalWeakTable<object, object>(); for (int i = 0; i < numObjects; i++) { cwt.Add(keys[i], values[i]); } for (int i = 0; i < numObjects; i++) { Assert.Same(values[i], cwt.GetValue(keys[i], _ => new object())); } for (int i = 0; i < numObjects; i++) { Assert.True(cwt.Remove(keys[i])); Assert.False(cwt.Remove(keys[i])); } for (int i = 0; i < numObjects; i++) { object ignored; Assert.False(cwt.TryGetValue(keys[i], out ignored)); } }
public void Should_release_value_when_there_are_no_more_references() { var table = new ConditionalWeakTable<TypeWithStrongReferenceThroughTable, TypeWithWeakReference>(); var strong = new TypeWithStrongReferenceThroughTable(); var weak = new TypeWithWeakReference() { WeakReference = new WeakReference(strong) }; table.Add(strong, weak); GC.Collect(); TypeWithWeakReference result = null; Assert.That(table.TryGetValue(strong, out result), Is.True); Assert.That(result, Is.SameAs(weak)); var weakHandleToStrong = new WeakReference(strong); strong = null; GC.Collect(); Assert.That(weakHandleToStrong.IsAlive, Is.False); }
public static NamingStylePreferences GetNamingStylesFromDictionary(IReadOnlyDictionary <string, object> allRawConventions) { if (_cache.TryGetValue(allRawConventions, out var value)) { return(value); } lock (_cacheLock) { if (!_cache.TryGetValue(allRawConventions, out value)) { value = ParseDictionary(allRawConventions); _cache.Add(allRawConventions, value); } return(value); } }
public static NamingStylePreferences GetNamingStylesFromDictionary(IReadOnlyDictionary <string, string> rawOptions) { if (_cache.TryGetValue(rawOptions, out var value)) { return(value); } lock (_cacheLock) { if (!_cache.TryGetValue(rawOptions, out value)) { value = ParseDictionary(rawOptions); _cache.Add(rawOptions, value); } return(value); } }
public override async Task Invoke(IOwinContext context) { bool bodyIsJson = context.Request.ContentType?.Contains(ContentType.Json) ?? false; if (bodyIsJson && (context.Request.Method == Http.POST || context.Request.Method == Http.PUT)) { var json = await Common.Utils.CommonUtils.GetRequestBodyFromRequestStream(context.Request); var body = JToken.Parse(json); RequestJsonBody.Add(context.Request, body); } await Next.Invoke(context); if (bodyIsJson) { RequestJsonBody.Remove(context.Request); } }
/* * Ensure that a key whose value has a reference to the key or a reference to another object * which has a reference to the key, gets automatically removed from the dictionary after GC * happens (provided there are no references to the value outside the dictionary.) * Also make sure the value gets gc’d as well. * * In this case we pass the same string array to the function, so keys and values have references to each other * (But only within the dictionary) * */ public static void TestKeyWithInsideReferences_Pass1(int length) { tbl = new ConditionalWeakTable <string, string>(); weakRefKeyArr = new WeakReference[length]; weakRefValArr = new WeakReference[length]; for (int i = 0; i < length; i++) { String key = "SomeTestString" + i.ToString(); String value = key; tbl.Add(key, value); // create a weak reference for the key weakRefKeyArr[i] = new WeakReference(key, true); weakRefValArr[i] = new WeakReference(value, true); } }
public static LinkerConfiguration GetInstance(LinkContext context, bool createIfNotFound = true) { if (!configurations.TryGetValue(context, out var instance) && createIfNotFound) { if (!context.TryGetCustomData("LinkerOptionsFile", out var linker_options_file)) { throw new Exception($"No custom linker options file was passed to the linker (using --custom-data LinkerOptionsFile=..."); } instance = new LinkerConfiguration(linker_options_file) { Context = context, }; configurations.Add(context, instance); } return(instance); }
static void Main(string[] args) { var table = new ConditionalWeakTable <string, Foo> { { "walterlv", new Foo("吕毅") }, { "lindexi", new Foo("林德熙") }, }; var time = DateTime.Now.ToString("T"); table.Add(time, new Foo("时间")); time = null; Console.WriteLine($"开始个数:{table.Count()}"); GC.Collect(); Console.WriteLine($"剩余个数:{table.Count()}"); Console.ReadLine(); }
private void SubscribeToDownloadProgress(IPackageDetails packageDetails) { Argument.IsNotNull(() => packageDetails); var packageDownloader = GetPackageDownloaderInstance(packageDetails); if (packageDownloader == null) { return; } var weakEvent = this.SubscribeToWeakGenericEvent <ProgressEventArgs>(packageDownloader, "ProgressAvailable", OnPackageDownloadProgress); if (weakEvent != null) { _packageEvents.Add(packageDetails, weakEvent); } }
public T[] Take <T>(int minimumLength) { var buffer = ArrayPool <T> .Shared.Rent(minimumLength); AtomicCounter cnt; if (_cwt.TryGetValue(buffer, out cnt)) { Interlocked.Increment(ref cnt.Count); } else { _cwt.Add(buffer, new AtomicCounter { Count = 1 }); } return(buffer); }
/* * Ensure that a key that has no managed references to it gets automatically removed from the * dictionary after GC happens. Also make sure the value gets gc’d as well. */ public static void TestKeyWithNoReferences_Pass1(int length) { tbl = new ConditionalWeakTable<string, string>(); weakRefKeyArr = new WeakReference[length]; weakRefValArr = new WeakReference[length]; for (int i = 0; i < length; i++) { String key = "KeyTestString" + i.ToString(); String value = "ValueTestString" + i.ToString(); tbl.Add(key, value); // create a weak reference for the key weakRefKeyArr[i] = new WeakReference(key, true); weakRefValArr[i] = new WeakReference(value, true); } }
private (ModuleMetadata metadata, ITemporaryStreamStorage storage) ReadModuleMetadataFrom( ObjectReader reader, SerializationKinds kind, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); GetTemporaryStorage(reader, kind, out var storage, out var length, cancellationToken); var storageStream = storage.ReadStream(cancellationToken); Contract.ThrowIfFalse(length == storageStream.Length); GetMetadata(storageStream, length, out var metadata, out var lifeTimeObject); // make sure we keep storageStream alive while Metadata is alive // we use conditional weak table since we can't control metadata liftetime s_lifetimeMap.Add(metadata, lifeTimeObject); return(metadata, storage); }
public VersionedSagaEntity(IContainSagaData sagaData, string lockTokenKey, VersionedSagaEntity original = null) { LockTokenKey = lockTokenKey; SagaData = DeepClone(sagaData); if (original != null) { original.ConcurrencyCheck(sagaData); versionCache = original.versionCache; version = original.version; version++; } else { versionCache = new ConditionalWeakTable <IContainSagaData, SagaVersion>(); versionCache.Add(sagaData, new SagaVersion(version)); } }
public void HandleCall(object instance, string methodIdentifier, object[] args, Type[] argTypes) { if (instance is INotifyPropertyChanged inpc && methodIdentifier.IndexOf(" .ctor ", StringComparison.InvariantCultureIgnoreCase) != -1) { var typeName = instance.GetType().FullName; if (_ignoredViewModels.Any(toIgnore => string.Equals(toIgnore, typeName))) { return; } // Base constructors would cause the same instance to be added without this check if (!_inpcInfos.TryGetValue(inpc, out _)) { _inpcInfos.Add(inpc, new InstanceInfo(_uniqueId++, args, argTypes)); } } }
public static JavaProxyObject GetProxy(object value) { if (value == null) { return(null); } lock (CachedValues) { JavaProxyObject proxy; if (CachedValues.TryGetValue(value, out proxy)) { return(proxy); } proxy = new JavaProxyObject(value); CachedValues.Add(value, proxy); return(proxy); } }
public static void Concurrent_Add_Read_Remove_DifferentObjects() { var cwt = new ConditionalWeakTable <object, object>(); DateTime end = DateTime.UtcNow + TimeSpan.FromSeconds(0.25); Parallel.For(0, Environment.ProcessorCount, i => { while (DateTime.UtcNow < end) { object key = new object(); object value = new object(); cwt.Add(key, value); Assert.Same(value, cwt.GetValue(key, _ => new object())); Assert.True(cwt.Remove(key)); Assert.False(cwt.Remove(key)); } }); }
internal static EventHandler <object> GetValueFromEquivalentKey( ConditionalWeakTable <EventHandler, EventHandler <object> > table, EventHandler key, ConditionalWeakTable <EventHandler, EventHandler <object> > .CreateValueCallback callback) { EventHandler <object> value; // Find the key in the table using a value check rather than an instance check. EventHandler existingKey = table.FindEquivalentKeyUnsafe(key, out value); if (existingKey == null) { value = callback(key); table.Add(key, value); } return(value); }
/// <summary> /// Create a factory delegate for creating instances of the specified actor type. /// </summary> /// <param name="actorType"> /// The type of actor to create. /// </param> /// <returns> /// A delegate that returns new instances of the actor. /// </returns> public Func <ActorBase> CreateActorFactory(Type actorType) { if (actorType == null) { throw new ArgumentNullException(nameof(actorType)); } return(() => { var scope = _scopeFactory.CreateScope(); var actorRef = scope.ServiceProvider.GetService(actorType); var actor = actorRef as ActorBase; _references.Add(actor, scope); return actor; }); }
internal static EventHandler <object> GetValueFromEquivalentKey( ConditionalWeakTable <EventHandler, EventHandler <object> > table, EventHandler key, ConditionalWeakTable <EventHandler, EventHandler <object> > .CreateValueCallback callback) { foreach (KeyValuePair <EventHandler, EventHandler <object> > item in table) { if (object.Equals(item.Key, key)) { return(item.Value); } } EventHandler <object> value = callback(key); table.Add(key, value); return(value); }
[Category("NotWorking")] // No ephemerons public void OldGenKeysMakeNewGenObjectsReachable() { if (GC.MaxGeneration == 0) /*Boehm doesn't handle ephemerons */ { Assert.Ignore("Not working on Boehm."); } var table = new ConditionalWeakTable <object, Val>(); var keys = new List <Key>(); // // This list references all keys for the duration of the program, so none // should be collected ever. // for (var x = 0; x < 1000; x++) { keys.Add(new Key { Foo = x }); } for (var i = 0; i < 1000; ++i) { // Insert all keys into the ConditionalWeakTable foreach (var key in keys) { table.Add(key, new Val { Foo = key.Foo }); } // Look up all keys to verify that they are still there foreach (var key in keys) { Assert.IsTrue(table.TryGetValue(key, out _), "#1-" + i.ToString() + "-k-" + key); } // Remove all keys from the ConditionalWeakTable foreach (var key in keys) { Assert.IsTrue(table.Remove(key), "#2-" + i.ToString() + "-k-" + key); } } }
PEFile LoadAssembly(object state) { MetadataReaderOptions options; if (DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections) { options = MetadataReaderOptions.ApplyWindowsRuntimeProjections; } else { options = MetadataReaderOptions.None; } PEFile module; // runs on background thread if (state is Stream stream) { // Read the module from a precrafted stream module = new PEFile(fileName, stream, metadataOptions: options); } else { // Read the module from disk (by default) stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); module = new PEFile(fileName, stream, PEStreamOptions.PrefetchEntireImage, metadataOptions: options); } if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) { try { this.debugInfoProvider = DebugInfoLoader.LoadSymbols(module); } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (InvalidOperationException) { // ignore any errors during symbol loading } } lock (loadedAssemblies) { loadedAssemblies.Add(module, this); } return(module); }
public static void RenderPath(this WorldView world, IVertexSource vertexSource, Color color, bool doDepthTest) { AAGLTesselator tesselator; if (!TesselatorsByWorld.TryGetValue(world, out tesselator)) { // Update reference and store in dictionary tesselator = new AAGLTesselator(world); TesselatorsByWorld.Add(world, tesselator); } // TODO: Necessary? // CheckLineImageCache(); // GL.Enable(EnableCap.Texture2D); // GL.BindTexture(TextureTarget.Texture2D, RenderOpenGl.ImageGlPlugin.GetImageGlPlugin(AATextureImages[color.Alpha0To255], false).GLTextureHandle); // the source is always all white so has no does not have its color changed by the alpha GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha); GL.Enable(EnableCap.Blend); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.Lighting); if (doDepthTest) { GL.Enable(EnableCap.DepthTest); } else { GL.Disable(EnableCap.DepthTest); } vertexSource.rewind(0); // the alpha has to come from the bound texture GL.Color4(color.red, color.green, color.blue, (byte)255); tesselator.Clear(); VertexSourceToTesselator.SendShapeToTesselator(tesselator, vertexSource); // now render it tesselator.RenderLastToGL(); }
public static unsafe PEReader OpenPEFile(string filePath, byte[] moduleBytes, out MemoryMappedViewAccessor mappedViewAccessor) { // If moduleBytes is specified create PEReader from the in memory array, not from a file on disk if (moduleBytes != null) { var peReader = new PEReader(ImmutableArray.Create <byte>(moduleBytes)); mappedViewAccessor = null; return(peReader); } // System.Reflection.Metadata has heuristic that tries to save virtual address space. This heuristic does not work // well for us since it can make IL access very slow (call to OS for each method IL query). We will map the file // ourselves to get the desired performance characteristics reliably. FileStream fileStream = null; MemoryMappedFile mappedFile = null; MemoryMappedViewAccessor accessor = null; try { // Create stream because CreateFromFile(string, ...) uses FileShare.None which is too strict fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1); mappedFile = MemoryMappedFile.CreateFromFile( fileStream, null, fileStream.Length, MemoryMappedFileAccess.Read, HandleInheritability.None, true); accessor = mappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read); var safeBuffer = accessor.SafeMemoryMappedViewHandle; var peReader = new PEReader((byte *)safeBuffer.DangerousGetHandle(), (int)safeBuffer.ByteLength); s_peReaderToPath.Add(peReader, filePath); // MemoryMappedFile does not need to be kept around. MemoryMappedViewAccessor is enough. mappedViewAccessor = accessor; accessor = null; return(peReader); } finally { accessor?.Dispose(); mappedFile?.Dispose(); fileStream?.Dispose(); } }
protected virtual void ShowWindowViewController( NSViewController viewController, MvxWindowPresentationAttribute attribute, MvxViewModelRequest request) { NSWindow window = null; MvxWindowController windowController = null; if (!string.IsNullOrEmpty(attribute.WindowControllerName)) { windowController = CreateWindowController(attribute); window = windowController.Window; } if (window == null) { window = CreateWindow(attribute); if (windowController == null) { windowController = CreateWindowController(window); windowController.ShouldCascadeWindows = attribute.ShouldCascadeWindows ?? MvxWindowPresentationAttribute.DefaultShouldCascadeWindows; } windowController.Window = window; } else { UpdateWindow(attribute, window); } window.Identifier = attribute.Identifier ?? viewController.GetType().Name; if (!string.IsNullOrEmpty(viewController.Title)) { window.Title = viewController.Title; } Windows.Add(window); window.ContentView = viewController.View; window.ContentViewController = viewController; windowController.ShowWindow(null); _windowsToWindowControllers.Add(window, windowController); }
public void Remove() { var cwt = new ConditionalWeakTable <object, object>(); object c = new Key(); cwt.Add(c, "x"); try { cwt.Remove(null); Assert.Fail("#0"); } catch (ArgumentNullException) { } Assert.IsFalse(cwt.Remove("x"), "#1"); Assert.IsTrue(cwt.Remove(c), "#2"); Assert.IsFalse(cwt.Remove(c), "#3"); }
/// <summary> /// Create the child ContentPresenter for the given item (could be data or a TabItem) /// </summary> /// <param name="item">The item.</param> private void CreateChildContentPresenter(object item) { if (item == null) { return; } object dummyObject = null; if (_wrappedContainers.TryGetValue(item, out dummyObject)) { return; } _wrappedContainers.Add(item, new object()); var cp = FindChildContentPresenter(item); if (cp != null) { return; } // the actual child to be added. cp.Tag is a reference to the TabItem cp = new ContentPresenter(); var container = GetContentContainer(item); var content = GetContent(item); var tabItemData = new TabControlItemData(container, content, ContentTemplate, item); cp.Tag = tabItemData; if (!IsLazyLoading) { ShowChildContent(cp, tabItemData); } cp.ContentTemplateSelector = ContentTemplateSelector; cp.ContentStringFormat = SelectedContentStringFormat; _itemsHolder.Children.Add(cp); }
public void TryGetValue() { var cwt = new ConditionalWeakTable <object, object>(); object res; object c = new Key(); cwt.Add(c, "foo"); try { cwt.TryGetValue(null, out res); Assert.Fail("#0"); } catch (ArgumentNullException) { } Assert.IsFalse(cwt.TryGetValue("foo", out res), "#1"); Assert.IsTrue(cwt.TryGetValue(c, out res), "#2"); Assert.AreEqual("foo", res, "#3"); }
public BufferPool Get() { if (!_threadLocal.IsValueCreated) { var bufferPool = new BufferPool(_serializationService); _strongReferences.Add(Thread.CurrentThread, bufferPool); _threadLocal.Value = new WeakReference(bufferPool); return(bufferPool); } else { var bufferPool = _threadLocal.Value.Target as BufferPool; if (bufferPool == null) { throw new HazelcastInstanceNotActiveException(); } return(bufferPool); } }
public static void Clear_AddThenEmptyRepeatedly_ItemsRemoved() { var cwt = new ConditionalWeakTable <object, object>(); object key = new object(), value = new object(); object result; for (int i = 0; i < 3; i++) { cwt.Add(key, value); Assert.True(cwt.TryGetValue(key, out result)); Assert.Same(value, result); cwt.Clear(); Assert.False(cwt.TryGetValue(key, out result)); Assert.Null(result); } }
/// <summary> /// Computes an unique runtime id (32bits) valid for the specified <see cref="object"/>. /// </summary> /// <returns>An unique runtime identifier (32bits)</returns> public static int ToRuntimeId(object instance) { if (instance == null) { return(0); } lock (RuntimeIds) { object rtid; if (!RuntimeIds.TryGetValue(instance, out rtid)) { count++; rtid = count; RuntimeIds.Add(instance, rtid); } return((int)rtid); } }
private static Dictionary <string, DataAcessor> GetDataAcessors(this IGetDataItems data) { //do acessos already exist Dictionary <string, DataAcessor> acessors; if (DataAcessorLut.TryGetValue(data, out acessors)) { return(acessors); } else { //make all acessors for this type and cache acessors = makeDataAcessors(data); DataAcessorLut.Add(data, acessors); //return the result return(acessors); } }
void IWpfTextViewConnectionListener.SubjectBuffersConnected(IWpfTextView textView, ConnectionReason reason, Collection <ITextBuffer> subjectBuffers) { lock (s_gate) { // only add roslyn type to tracking map foreach (var buffer in subjectBuffers.Where(b => IsSupportedContentType(b.ContentType))) { if (!s_map.TryGetValue(buffer, out var set)) { set = new HashSet <ITextView>(); s_map.Add(buffer, set); } set.Add(textView); DebugRegisterView_NoLock(textView); } } this.SubjectBuffersConnected?.Invoke(this, new SubjectBuffersConnectedEventArgs(textView, subjectBuffers.ToReadOnlyCollection())); }
private static async Task <ImmutableArray <SearchResult> > TryFilterPreviousSearchResultsAsync( Project project, Document searchDocument, string pattern, PatternMatcher nameMatcher, PatternMatcher containerMatcherOpt, ArrayBuilder <PatternMatch> nameMatches, ArrayBuilder <PatternMatch> containerMatches, CancellationToken cancellationToken) { // Searching an entire project. See if we already performed that same // search with a substring of the current pattern. if so, we can use // the previous result and just filter that down. This is useful for // the common case where a user types some pattern, then keeps adding // to it. ImmutableArray <SearchResult> searchResults; if (s_lastProjectSearchCache.TryGetValue(project, out var previousResult) && pattern.StartsWith(previousResult.Item1)) { // We can reuse the previous results and just filter them. searchResults = FilterPreviousResults( previousResult.Item2, nameMatcher, containerMatcherOpt, nameMatches, containerMatches, cancellationToken); } else { // Didn't have previous results. Or it was a very different pattern. // Can't reuse. searchResults = await ComputeSearchResultsAsync( project, searchDocument, nameMatcher, containerMatcherOpt, nameMatches, containerMatches, cancellationToken).ConfigureAwait(false); } // Would like to use CWT.AddOrUpdate. But that is not available on the // version of .Net that we're using. So we need to take lock as we're // making multiple mutations. lock (s_lastProjectSearchCache) { s_lastProjectSearchCache.Remove(project); s_lastProjectSearchCache.Add(project, Tuple.Create(pattern, searchResults)); } return(searchResults); }
// this test ensures that while manipulating keys (through add/remove/lookup // in the dictionary the overriden GetHashCode(), Equals(), and ==operator do not get invoked. // Earlier implementation was using these functions virtually so overriding them would result in // the overridden functions being invoked. But later on Ati changed implementation to use // Runtime.GetHashCode and Object.ReferenceEquals so this test makes sure that overridden functions never get invoked. public static void TestOverrides() { string[] stringArr = new string[50]; for (int i = 0; i < 50; i++) { stringArr[i] = "SomeTestString" + i.ToString(); } ConditionalWeakTable<string, string> tbl = new ConditionalWeakTable<string, string>(); string str; for (int i = 0; i < stringArr.Length; i++) { tbl.Add(stringArr[i], stringArr[i]); tbl.TryGetValue(stringArr[i], out str); tbl.Remove(stringArr[i]); } }
public static void Add(int numObjects) { // Isolated to ensure we drop all references even in debug builds where lifetime is extended by the JIT to the end of the method Func<int, Tuple<ConditionalWeakTable<object, object>, WeakReference[], WeakReference[]>> body = count => { object[] keys = Enumerable.Range(0, count).Select(_ => new object()).ToArray(); object[] values = Enumerable.Range(0, count).Select(_ => new object()).ToArray(); var cwt = new ConditionalWeakTable<object, object>(); for (int i = 0; i < count; i++) { cwt.Add(keys[i], values[i]); } for (int i = 0; i < count; i++) { object value; Assert.True(cwt.TryGetValue(keys[i], out value)); Assert.Same(values[i], value); Assert.Same(value, cwt.GetOrCreateValue(keys[i])); Assert.Same(value, cwt.GetValue(keys[i], _ => new object())); } return Tuple.Create(cwt, keys.Select(k => new WeakReference(k)).ToArray(), values.Select(v => new WeakReference(v)).ToArray()); }; Tuple<ConditionalWeakTable<object, object>, WeakReference[], WeakReference[]> result = body(numObjects); GC.Collect(); Assert.NotNull(result.Item1); for (int i = 0; i < numObjects; i++) { Assert.False(result.Item2[i].IsAlive, $"Expected not to find key #{i}"); Assert.False(result.Item3[i].IsAlive, $"Expected not to find value #{i}"); } }
public static void AddTest() { ConditionalWeakTable<object, object> cwt = new ConditionalWeakTable<object, object>(); object key = new object(); object value = new object(); object obj = null; cwt.Add(key, value); Assert.True(cwt.TryGetValue(key, out value)); Assert.Equal(value, cwt.GetOrCreateValue(key)); Assert.Equal(value, cwt.GetValue(key , k => new object())); WeakReference<object> wrValue = new WeakReference<object>(value, false); WeakReference<object> wrkey = new WeakReference<object>(key, false); key = null; value = null; GC.Collect(); // key and value must be collected Assert.False(wrValue.TryGetTarget(out obj)); Assert.False(wrkey.TryGetTarget(out obj)); }
/* * Ensure that a key whose value is referenced outside the dictionary does not get * automatically removed from the dictionary after GC happens and the key doesn't get gc'd. */ public static void TestKeyWithOutsideReferences_Pass1(int length) { tbl = new ConditionalWeakTable<string, string>(); weakRefKeyArr = new WeakReference[length]; weakRefValArr = new WeakReference[length]; for (int i = 0; i < length; i++) { String key = "OtherKeyTestString" + i.ToString(); String value = "OtherValueTestString" + i.ToString();; tbl.Add(key, value); // these assignments should prevent the object from being collected if (i == 0) { key0 = key; value0 = value; } if (i == 21) { key21 = key; value21 = value; } if (i == 99) { key99 = key; value99 = value; } // create a weak reference for the key weakRefKeyArr[i] = new WeakReference(key, true); weakRefValArr[i] = new WeakReference(value, true); } }
static void FillStuff (ConditionalWeakTable <object,object> cwt, out List<object> keepAlive, out List<WeakReference> keys) { keepAlive = new List<object> (); keys = new List<WeakReference> (); object a = new Key (); object b = new Key (); object c = new Key (); cwt.Add (a, new string ("str0".ToCharArray ())); cwt.Add (b, "str1"); cwt.Add (c, new Link (a)); keepAlive.Add (c); keys.Add (new WeakReference(a)); keys.Add (new WeakReference(b)); keys.Add (new WeakReference(c)); }
public void TryGetValue () { var cwt = new ConditionalWeakTable <object,object> (); object res; object c = new Key (); cwt.Add (c, "foo"); try { cwt.TryGetValue (null, out res); Assert.Fail ("#0"); } catch (ArgumentNullException) {} Assert.IsFalse (cwt.TryGetValue ("foo", out res), "#1"); Assert.IsTrue (cwt.TryGetValue (c, out res), "#2"); Assert.AreEqual ("foo", res, "#3"); }
// Create a new test with the given table style and object count. public TestSet(TableStyle ts, int count) { // Use one random number generator for the life of the test. Could support explicit seeds for // reproducible tests here. m_rng = new Random(); // Remember our parameters. m_count = count; m_style = ts; // Various arrays. m_nodes = new Node[count]; // The array of objects m_collected = new bool[count]; // Records whether each object has been collected (entries are set by // the finalizer on Node) m_marks = new bool[count]; // Array used during individual test runs to calculate whether each // object should still be alive (allocated once here to avoid // injecting further garbage collections at run time) // Allocate each object (Node). Each knows its own unique ID (the index into the node array) and has a // back pointer to this test object (so it can phone home to report its own collection at finalization // time). for (int i = 0; i < count; i++) m_nodes[i] = new Node(this, i); // Determine how many handles we need to allocate given the number of nodes. This varies based on the // table style. switch (ts) { case TableStyle.Unconnected: // Primaries and secondaries are completely different objects so we split our nodes in half and // allocate that many handles. m_handleCount = count / 2; break; case TableStyle.ForwardLinked: // Nodes are primaries in one handle and secondary in another except one that falls off the end. // So we have as many handles as nodes - 1. m_handleCount = count - 1; break; case TableStyle.BackwardLinked: // Nodes are primaries in one handle and secondary in another except one that falls off the end. // So we have as many handles as nodes - 1. m_handleCount = count - 1; break; case TableStyle.Random: // Each node is a primary in some handle (secondaries are selected from amongst all the same nodes // randomly). So we have as many nodes as handles. m_handleCount = count; break; } // Allocate an array of HandleSpecs. These aren't the real handles, just structures that allow us // remember what's in each handle (in terms of the node index number for the primary and secondary). // We need to track this information separately because we can't access the real handles directly // (ConditionalWeakTable hides them) and we need to recall exactly what the primary and secondary of // each handle is so we can compute our own notion of object liveness later. m_handles = new HandleSpec[m_handleCount]; // Initialize the handle specs to assign objects to handles based on the table style. for (int i = 0; i < m_handleCount; i++) { int primary = -1, secondary = -1; switch (ts) { case TableStyle.Unconnected: // Assign adjacent nodes to the primary and secondary of each handle. primary = i * 2; secondary = (i * 2) + 1; break; case TableStyle.ForwardLinked: // Primary of each handle is the secondary of the last handle. primary = i; secondary = i + 1; break; case TableStyle.BackwardLinked: // Primary of each handle is the secondary of the next handle. primary = i + 1; secondary = i; break; case TableStyle.Random: // Primary is each node in sequence, secondary is any of the nodes randomly. primary = i; secondary = m_rng.Next(m_handleCount); break; } m_handles[i].Set(primary, secondary); } // Allocate a ConditionalWeakTable mapping Node keys to Node values. m_table = new ConditionalWeakTable<Node, Node>(); // Using our handle specs computed above add each primary/secondary node pair to the // ConditionalWeakTable in turn. This causes the ConditionalWeakTable to allocate a dependent handle // for each entry with the primary and secondary objects we specified as keys and values (note that // this scheme prevents us from creating multiple handles with the same primary though if this is // desired we could achieve it by allocating multiple ConditionalWeakTables). for (int i = 0; i < m_handleCount; i++) m_table.Add(m_nodes[m_handles[i].m_primary], m_nodes[m_handles[i].m_secondary]); }
static List<WeakReference> FillWithNetwork (ConditionalWeakTable <object,object> cwt) { const int K = 500; object[] keys = new object [K]; for (int i = 0; i < K; ++i) keys[i] = new object (); Random rand = new Random (); /*produce a complex enough network of links*/ for (int i = 0; i < K; ++i) cwt.Add (keys [i], new Link (keys [rand.Next (K)])); var res = new List<WeakReference> (); for (int i = 0; i < 10; ++i) res.Add (new WeakReference (keys [rand.Next (K)])); Array.Clear (keys, 0, keys.Length); return res; }
private static List<InstanceInitializationData> GetListForCurrentRequest( ConditionalWeakTable<HttpContext, List<InstanceInitializationData>> dictionary) { HttpContext currentRequest = HttpContext.Current; if (currentRequest == null) { return new List<InstanceInitializationData>(); } lock (dictionary) { List<InstanceInitializationData> currentRequestInstances; if (!dictionary.TryGetValue(currentRequest, out currentRequestInstances)) { dictionary.Add(currentRequest, currentRequestInstances = new List<InstanceInitializationData>(capacity: 32)); } return currentRequestInstances; } }
public void Add () { var cwt = new ConditionalWeakTable <object,object> (); object c = new Key (); cwt.Add (c, new Link (c)); try { cwt.Add (c, new Link (c)); Assert.Fail ("#0"); } catch (ArgumentException) {} cwt.Add ("zzz", null);//ok try { cwt.Add (null, new Link (c)); Assert.Fail ("#1"); } catch (ArgumentNullException) {} }
public void InsertStress () { if (GC.MaxGeneration == 0) /*Boehm doesn't handle ephemerons */ Assert.Ignore ("Not working on Boehm."); var cwt = new ConditionalWeakTable <object,object> (); var a = new object (); var b = new object (); cwt.Add (a, new object ()); cwt.Add (b, new object ()); List<WeakReference> res = null; ThreadStart dele = () => { res = FillWithNetwork (cwt); }; var th = new Thread(dele); th.Start (); th.Join (); GC.Collect (); GC.Collect (); for (int i = 0; i < res.Count; ++i) Assert.IsFalse (res [i].IsAlive, "#r" + i); }
public static void Clear_AllValuesRemoved(int numObjects) { var cwt = new ConditionalWeakTable<object, object>(); MethodInfo clear = cwt.GetType().GetMethod("Clear", BindingFlags.NonPublic | BindingFlags.Instance); if (clear == null) { // Couldn't access the Clear method; skip the test. return; } object[] keys = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); object[] values = Enumerable.Range(0, numObjects).Select(_ => new object()).ToArray(); for (int iter = 0; iter < 2; iter++) { // Add the objects for (int i = 0; i < numObjects; i++) { cwt.Add(keys[i], values[i]); Assert.Same(values[i], cwt.GetValue(keys[i], _ => new object())); } // Clear the table clear.Invoke(cwt, null); // Verify the objects are removed for (int i = 0; i < numObjects; i++) { object ignored; Assert.False(cwt.TryGetValue(keys[i], out ignored)); } // Do it a couple of times, to make sure the table is still usable after a clear. } }
static List<GCHandle> FillTable3 (ConditionalWeakTable <object,object> cwt) { var handles = new List<GCHandle> (); var a = (object)10; var b = (object)20; var k1 = (object)30; var k2 = (object)40; handles.Add (GCHandle.Alloc (a, GCHandleType.Pinned)); handles.Add (GCHandle.Alloc (b, GCHandleType.Pinned)); handles.Add (GCHandle.Alloc (k1, GCHandleType.Pinned)); handles.Add (GCHandle.Alloc (k2, GCHandleType.Pinned)); cwt.Add (a, k1); cwt.Add (b, k2); return handles; }
public void OldGenKeysMakeNewGenObjectsReachable () { if (GC.MaxGeneration == 0) /*Boehm doesn't handle ephemerons */ Assert.Ignore ("Not working on Boehm."); ConditionalWeakTable<object, Val> table = new ConditionalWeakTable<object, Val>(); List<Key> keys = new List<Key>(); // // This list references all keys for the duration of the program, so none // should be collected ever. // for (int x = 0; x < 1000; x++) keys.Add (new Key () { Foo = x }); for (int i = 0; i < 1000; ++i) { // Insert all keys into the ConditionalWeakTable foreach (var key in keys) table.Add (key, new Val () { Foo = key.Foo }); // Look up all keys to verify that they are still there Val val; foreach (var key in keys) Assert.IsTrue (table.TryGetValue (key, out val), "#1-" + i + "-k-" + key); // Remove all keys from the ConditionalWeakTable foreach (var key in keys) Assert.IsTrue (table.Remove (key), "#2-" + i + "-k-" + key); } }
static void FillWithFinalizable (ConditionalWeakTable <object,object> cwt) { object a = new object (); object b = new FinalizableLink (0, a, cwt); cwt.Add (a, "foo"); cwt.Add (b, "bar"); for (int i = 1; i < 20; ++i) { b = new FinalizableLink (i, b, cwt); cwt.Add (b, i); } }
public static void Concurrent_AddMany_DropReferences() // no asserts, just making nothing throws { var cwt = new ConditionalWeakTable<object, object>(); for (int i = 0; i < 10000; i++) { cwt.Add(i.ToString(), i.ToString()); if (i % 1000 == 0) GC.Collect(); } }
internal static EventHandler<object> GetValueFromEquivalentKey( ConditionalWeakTable<EventHandler, EventHandler<object>> table, EventHandler key, ConditionalWeakTable<EventHandler, EventHandler<object>>.CreateValueCallback callback) { EventHandler<object> value; // Find the key in the table using a value check rather than an instance check. EventHandler existingKey = table.FindEquivalentKeyUnsafe(key, out value); if (existingKey == null) { value = callback(key); table.Add(key, value); } return value; }
public static void Concurrent_Add_Read_Remove_DifferentObjects() { var cwt = new ConditionalWeakTable<object, object>(); DateTime end = DateTime.UtcNow + TimeSpan.FromSeconds(0.25); Parallel.For(0, Environment.ProcessorCount, i => { while (DateTime.UtcNow < end) { object key = new object(); object value = new object(); cwt.Add(key, value); Assert.Same(value, cwt.GetValue(key, _ => new object())); Assert.True(cwt.Remove(key)); Assert.False(cwt.Remove(key)); } }); }
// add the handler to the CWT - this keeps the handler alive throughout // the lifetime of the target, without prolonging the lifetime of // the target void AddHandlerToCWT(Delegate handler, ConditionalWeakTable<object, object> cwt) { object value; object target = handler.Target; if (target == null) target = StaticSource; if (!cwt.TryGetValue(target, out value)) { // 99% case - the target only listens once cwt.Add(target, handler); } else { // 1% case - the target listens multiple times // we store the delegates in a list List<Delegate> list = value as List<Delegate>; if (list == null) { // lazily allocate the list, and add the old handler Delegate oldHandler = value as Delegate; list = new List<Delegate>(); list.Add(oldHandler); // install the list as the CWT value cwt.Remove(target); cwt.Add(target, list); } // add the new handler to the list list.Add(handler); } }
public static void AddRemove_DropValue() { var key = new object(); var value = new object(); var cwt = new ConditionalWeakTable<object, object>(); cwt.Add(key, value); cwt.Remove(key); // Verify that the removed entry is not keeping the value alive var wrValue = new WeakReference(value); value = null; GC.Collect(); Assert.False(wrValue.IsAlive); GC.KeepAlive(cwt); GC.KeepAlive(key); }
public void InsertStress () { var cwt = new ConditionalWeakTable <object,object> (); var a = new object (); var b = new object (); cwt.Add (a, new object ()); cwt.Add (b, new object ()); List<WeakReference> res = null; ThreadStart dele = () => { res = FillWithNetwork (cwt); }; var th = new Thread(dele); th.Start (); th.Join (); GC.Collect (); GC.Collect (); for (int i = 0; i < res.Count; ++i) Assert.IsFalse (res [i].IsAlive, "#r" + i); }
public void InsertStress () { if (GC.MaxGeneration == 0) /*Boehm doesn't handle ephemerons */ Assert.Ignore ("Not working on Boehm."); var cwt = new ConditionalWeakTable <object,object> (); var a = new object (); var b = new object (); cwt.Add (a, new object ()); cwt.Add (b, new object ()); List<WeakReference> res = null; FinalizerHelpers.PerformNoPinAction (() => { res = FillWithNetwork (cwt); }); GC.Collect (); GC.Collect (); for (int i = 0; i < res.Count; ++i) Assert.IsFalse (res [i].IsAlive, "#r" + i); }
public void Remove () { var cwt = new ConditionalWeakTable <object,object> (); object c = new Key (); cwt.Add (c, "x"); try { cwt.Remove (null); Assert.Fail ("#0"); } catch (ArgumentNullException) {} Assert.IsFalse (cwt.Remove ("x"), "#1"); Assert.IsTrue (cwt.Remove (c), "#2"); Assert.IsFalse (cwt.Remove (c), "#3"); }