public void RegisterEventHandler(EventHandler <TEventArgs> handler) { lock (weakReferences) { weakReferences.Clear(true); weakReferences.Add(handler); } }
public void TestUnloadViaScroll() { WeakList <Container> references = new WeakList <Container>(); AddStep("populate panels", () => { references.Clear(); for (int i = 0; i < 16; i++) { flow.Add(new Container { Size = new Vector2(128), Children = new Drawable[] { new DelayedLoadUnloadWrapper(() => { var container = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] { new TestBox { RelativeSizeAxes = Axes.Both } }, }; references.Add(container); return(container); }, 500, 2000), new SpriteText { Text = i.ToString() }, } }); } flow.Add( new Container { Size = new Vector2(128, 1280), }); }); AddUntilStep("references loaded", () => references.Count() == 16 && references.All(c => c.IsLoaded)); AddStep("scroll to end", () => scroll.ScrollToEnd()); AddUntilStep("references lost", () => { GC.Collect(); return(!references.Any()); }); AddStep("scroll to start", () => scroll.ScrollToStart()); AddUntilStep("references restored", () => references.Count() == 16); }
public void Test() { Random rand = new Random(3); List <string> list1 = new List <string>(); WeakList <string> list2 = new WeakList <string>(); for (int x = 0; x < 1000; x++) { string str = x.ToString(); list1.Add(str); list2.Add(str); if (!list1.SequenceEqual(list2)) { throw new Exception("Lists are not the same."); } } for (int x = 1000; x < 2000; x++) { string str = x.ToString(); string removeItem = list1[rand.Next(list1.Count)]; list1.Remove(removeItem); list2.Remove(removeItem); if (!list1.SequenceEqual(list2)) { throw new Exception("Lists are not the same."); } list1.Add(str); list2.Add(str); if (!list1.SequenceEqual(list2)) { throw new Exception("Lists are not the same."); } } for (int x = 0; x < 100; x++) { list1.RemoveAt(rand.Next(list1.Count)); GC.Collect(); if (!list1.SequenceEqual(list2)) { throw new Exception("Lists are not the same."); } } list2.Clear(); foreach (string data in list2) { throw new Exception(); } }
public void TestRemovedStillUnload() { WeakList <Container> references = new WeakList <Container>(); AddStep("populate panels", () => { references.Clear(); for (int i = 0; i < 16; i++) { flow.Add(new Container { Size = new Vector2(128), Children = new Drawable[] { new DelayedLoadUnloadWrapper(() => { var container = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] { new TestBox { RelativeSizeAxes = Axes.Both } }, }; references.Add(container); return(container); }, 500, 2000), new SpriteText { Text = i.ToString() }, } }); } }); AddUntilStep("references loaded", () => references.Count() == 16 && references.All(c => c.IsLoaded)); AddAssert("check schedulers present", () => scroll.Scheduler.HasPendingTasks); AddStep("Remove all panels", () => flow.Clear(false)); AddUntilStep("repeating schedulers removed", () => !scroll.Scheduler.HasPendingTasks); AddUntilStep("references lost", () => { GC.Collect(); return(!references.Any()); }); }
public void Test_GcCollect() { var weakList = new WeakList <object>(); weakList.Add(new Object()); GC.Collect(); GC.WaitForPendingFinalizers(); weakList.Clear(true); Assert.IsTrue(weakList.Count == 0, "Item must be collected by the GC collector"); }
public void Test() { var rand = new Random(3); List<string> list1 = new List<string>(); WeakList<string> list2 = new WeakList<string>(); for (int x = 0; x < 1000; x++) { var str = x.ToString(); list1.Add(str); list2.Add(str); if (!list1.SequenceEqual(list2)) throw new Exception("Lists are not the same."); } for (int x = 1000; x < 2000; x++) { var str = x.ToString(); var removeItem = list1[rand.Next(list1.Count)]; list1.Remove(removeItem); list2.Remove(removeItem); if (!list1.SequenceEqual(list2)) throw new Exception("Lists are not the same."); list1.Add(str); list2.Add(str); if (!list1.SequenceEqual(list2)) throw new Exception("Lists are not the same."); } for (int x = 0; x < 100; x++) { list1.RemoveAt(rand.Next(list1.Count)); GC.Collect(); if (!list1.SequenceEqual(list2)) throw new Exception("Lists are not the same."); } list2.Clear(); foreach (var data in list2) throw new Exception(); }
public void TestCountIsZeroAfterClear() { object obj = new object(); var weakRef = new WeakReference <object>(obj); var list = new WeakList <object> { obj, weakRef }; list.Clear(); Assert.That(list.Count(), Is.Zero); Assert.That(list, Does.Not.Contain(obj)); Assert.That(list.Contains(weakRef), Is.False); GC.KeepAlive(obj); }
public void Test_GcCannotCollect() { var weakList = new WeakList <object>(); //holding strong reference var item = new Object(); TestContext.Properties.Add("item", item); weakList.Add(item); GC.Collect(); GC.WaitForPendingFinalizers(); weakList.Clear(true); Assert.AreEqual(1, weakList.Count); TestContext.Properties.Remove("item"); }
public void Test_GCCannotCollectWholeList() { var items = new Object[10000]; for (int i = 0; i < 10000; i++) { items.SetValue(new Object(), i); } TestContext.Properties.Add("items", items); var weakList = new WeakList <object>(items); GC.Collect(); GC.WaitForPendingFinalizers(); weakList.Clear(true); Assert.AreEqual(10000, weakList.Count); TestContext.Properties.Remove("items"); }
public static void LogAndFlush() { if (!DebugUtils.IsDebugBuild) { return; } lock (loading_components) { Logger.Log($"⏳ Currently loading components ({loading_components.Count()})"); foreach (var c in loading_components.OrderBy(c => c.LoadThread?.Name).ThenBy(c => c.LoadState)) { Logger.Log(c.ToString()); Logger.Log($"- thread: {c.LoadThread?.Name ?? "none"}"); Logger.Log($"- state: {c.LoadState}"); } loading_components.Clear(); Logger.Log("🧵 Task schedulers"); Logger.Log(CompositeDrawable.SCHEDULER_STANDARD.GetStatusString()); Logger.Log(CompositeDrawable.SCHEDULER_LONG_LOAD.GetStatusString()); } ThreadPool.GetAvailableThreads(out int workerAvailable, out int completionAvailable); ThreadPool.GetMinThreads(out int workerMin, out int completionMin); ThreadPool.GetMaxThreads(out int workerMax, out int completionMax); Logger.Log("🎱 Thread pool"); // TODO: use after net6 // Logger.Log($"threads: {ThreadPool.ThreadCount:#,0}"); // Logger.Log($"work pending: {ThreadPool.PendingWorkItemCount:#,0}"); // Logger.Log($"work completed: {ThreadPool.CompletedWorkItemCount:#,0}"); Logger.Log($"worker: min {workerMin,-6:#,0} max {workerMax,-6:#,0} available {workerAvailable,-6:#,0}"); Logger.Log($"completion: min {completionMin,-6:#,0} max {completionMax,-6:#,0} available {completionAvailable,-6:#,0}"); }
public void TestTasksCanceledDuringLoadSequence() { var references = new WeakList <TestBox>(); AddStep("populate panels", () => { references.Clear(); for (int i = 0; i < 16; i++) { DelayedLoadUnloadWrapper loadUnloadWrapper; flow.Add(new Container { Size = new Vector2(128), Child = loadUnloadWrapper = new DelayedLoadUnloadWrapper(() => { var content = new TestBox { RelativeSizeAxes = Axes.Both }; references.Add(content); return(content); }, 0), }); // cancel load tasks after the delayed load has started. loadUnloadWrapper.DelayedLoadStarted += _ => game.Schedule(() => loadUnloadWrapper.UnbindAllBindables()); } }); AddStep("remove all panels", () => flow.Clear(false)); AddUntilStep("references lost", () => { GC.Collect(); return(!references.Any()); }); }
public void TestAddAfterClear() { var objects = new List <object> { new object(), new object(), new object(), }; object newObject = new object(); var list = new WeakList <object>(); foreach (object o in objects) { list.Add(o); } list.Clear(); list.Add(newObject); Assert.That(list.Count(), Is.EqualTo(1)); Assert.That(list, Does.Contain(newObject)); }
/// <summary> /// Remove all bound <see cref="Bindable{T}"/>s via <see cref="GetBoundCopy"/> or <see cref="BindTo"/>. /// </summary> public void UnbindBindings() { Bindings?.ForEachAlive(b => b.Unbind(this)); Bindings?.Clear(); }
/// <summary> /// Unbind any events bound to <see cref="ValueChanged"/> and <see cref="DisabledChanged"/>, along with /// removing all bound <see cref="Bindable{T}"/>s via <see cref="GetBoundCopy"/> or <see cref="BindTo"/>. /// </summary> public void UnbindAll() { ValueChanged = null; DisabledChanged = null; bindings.Clear(); }
/// <summary> /// Remove all bound <see cref="Bindable{T}"/>s via <see cref="GetBoundCopy"/> or <see cref="BindTo"/>. /// </summary> public void UnbindBindings() { Bindings?.Clear(); }
public void TestRemoveThenAdd() { WeakList <Container> references = new WeakList <Container>(); int loadCount = 0; AddStep("populate panels", () => { references.Clear(); loadCount = 0; for (int i = 0; i < 16; i++) { flow.Add(new Container { Size = new Vector2(128), Children = new Drawable[] { new DelayedLoadUnloadWrapper(() => { TestBox testBox; var container = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] { testBox = new TestBox { RelativeSizeAxes = Axes.Both } }, }; testBox.OnLoadComplete += _ => { references.Add(container); loadCount++; }; return(container); }, 500, 2000), new SpriteText { Text = i.ToString() }, } }); } }); IReadOnlyList <Container> previousChildren = null; AddUntilStep("all loaded", () => loadCount == 16); AddStep("Remove all panels", () => { previousChildren = flow.Children.ToList(); flow.Clear(false); }); AddStep("Add panels back", () => flow.Children = previousChildren); AddWaitStep("wait for potential unload", 20); AddAssert("load count hasn't changed", () => loadCount == 16); }