Remove VisualElement finalizer (#918)
* [Controls] Add repo for bugzilla 55365 * Remove finalizer from VisualElement * Remove unused using directive * Removing test for 44074 * Update docs
This commit is contained in:
Родитель
f01cf88040
Коммит
b3f6d80a1b
|
@ -0,0 +1,90 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using Xamarin.Forms.CustomAttributes;
|
||||||
|
using Xamarin.Forms.Internals;
|
||||||
|
#if UITEST
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Xamarin.Forms.Controls.Issues
|
||||||
|
{
|
||||||
|
[Preserve(AllMembers = true)]
|
||||||
|
[Issue(IssueTracker.Bugzilla, 55365, "~VisualElement crashes with System.Runtime.InteropServices.COMException", PlatformAffected.UWP)]
|
||||||
|
public class Bugzilla55365 : TestContentPage
|
||||||
|
{
|
||||||
|
readonly StackLayout _itemsPanel = new StackLayout();
|
||||||
|
readonly DataTemplate _itemTemplate = new DataTemplate(CreateBoxView);
|
||||||
|
readonly StackLayout _layout = new StackLayout();
|
||||||
|
|
||||||
|
#if UITEST
|
||||||
|
[Test]
|
||||||
|
public void ForcingGCDoesNotCrash()
|
||||||
|
{
|
||||||
|
RunningApp.WaitForElement("Clear");
|
||||||
|
RunningApp.Tap("Clear");
|
||||||
|
RunningApp.Tap("Garbage");
|
||||||
|
RunningApp.WaitForElement("Success");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected override void Init()
|
||||||
|
{
|
||||||
|
var viewModel = new ObservableCollection<_55365Item>
|
||||||
|
{
|
||||||
|
new _55365Item { Subject = 65 }
|
||||||
|
};
|
||||||
|
|
||||||
|
viewModel.CollectionChanged += OnCollectionChanged;
|
||||||
|
|
||||||
|
_itemsPanel.BindingContext = viewModel;
|
||||||
|
|
||||||
|
foreach (_55365Item item in viewModel)
|
||||||
|
{
|
||||||
|
_itemTemplate.SetValue(BindingContextProperty, item);
|
||||||
|
var view = (View)_itemTemplate.CreateContent();
|
||||||
|
_itemsPanel.Children.Add(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
var clearButton = new Button { Text = "Clear", Command = new Command(o => viewModel.Clear()) };
|
||||||
|
_layout.Children.Add(clearButton);
|
||||||
|
|
||||||
|
var collectButton = new Button { Text = "Garbage", Command = new Command(o =>
|
||||||
|
{
|
||||||
|
GC.Collect();
|
||||||
|
GC.WaitForPendingFinalizers();
|
||||||
|
_layout.Children.Add(new Label {Text = "Success"});
|
||||||
|
}) };
|
||||||
|
_layout.Children.Add(collectButton);
|
||||||
|
_layout.Children.Add(_itemsPanel);
|
||||||
|
|
||||||
|
Content = _layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object CreateBoxView()
|
||||||
|
{
|
||||||
|
var boxView1 = new BoxView { HeightRequest = 100, Color = new Color(0.55, 0.23, 0.147) };
|
||||||
|
var setter1 = new Setter { Property = BoxView.ColorProperty, Value = "#FF2879DD" };
|
||||||
|
var trigger1 = new DataTrigger(typeof(BoxView)) { Binding = new Binding("Subject"), Value = 65 };
|
||||||
|
trigger1.Setters.Add(setter1);
|
||||||
|
boxView1.Triggers.Add(trigger1);
|
||||||
|
return boxView1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Action == NotifyCollectionChangedAction.Reset)
|
||||||
|
{
|
||||||
|
// reset the list
|
||||||
|
_itemsPanel.Children.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Preserve(AllMembers = true)]
|
||||||
|
public class _55365Item
|
||||||
|
{
|
||||||
|
public int Subject { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -282,6 +282,7 @@
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla53909.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla53909.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)ListViewNRE.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)ListViewNRE.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla55745.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla55745.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla55365.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)_Template.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)_Template.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Issue1028.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Issue1028.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Issue1075.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Issue1075.cs" />
|
||||||
|
|
|
@ -109,42 +109,5 @@ namespace Xamarin.Forms.Core.UnitTests
|
||||||
collection.Remove (behavior);
|
collection.Remove (behavior);
|
||||||
Assert.Null (behavior.AssociatedObject);
|
Assert.Null (behavior.AssociatedObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
//https://bugzilla.xamarin.com/show_bug.cgi?id=44074
|
|
||||||
public void TestBehaviorsAreDetachedBeforeGarbageCollection()
|
|
||||||
{
|
|
||||||
WeakReference weakBindable = null;
|
|
||||||
|
|
||||||
var attachCount = MockBehavior<VisualElement>.AttachCount;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
Action create = null;
|
|
||||||
create = () =>
|
|
||||||
{
|
|
||||||
if (i++ < 1024)
|
|
||||||
{
|
|
||||||
create();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bindable = new MockBindable
|
|
||||||
{
|
|
||||||
Behaviors = {
|
|
||||||
new MockBehavior<VisualElement> ()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
weakBindable = new WeakReference(bindable);
|
|
||||||
};
|
|
||||||
|
|
||||||
create();
|
|
||||||
|
|
||||||
GC.Collect();
|
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
GC.Collect();
|
|
||||||
|
|
||||||
Assert.False(weakBindable.IsAlive);
|
|
||||||
Assert.AreEqual(attachCount, MockBehavior<VisualElement>.AttachCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -796,18 +796,5 @@ namespace Xamarin.Forms
|
||||||
|
|
||||||
public bool Result { get; set; }
|
public bool Result { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
~VisualElement()
|
|
||||||
{
|
|
||||||
if (!GetIsDefault(BehaviorsProperty)) {
|
|
||||||
var behaviors = GetValue(BehaviorsProperty) as AttachedCollection<Behavior>;
|
|
||||||
behaviors.DetachFrom(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetIsDefault(TriggersProperty)) {
|
|
||||||
var triggers = GetValue(TriggersProperty) as AttachedCollection<TriggerBase>;
|
|
||||||
triggers.DetachFrom(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -352,22 +352,6 @@
|
||||||
<remarks>To be added.</remarks>
|
<remarks>To be added.</remarks>
|
||||||
</Docs>
|
</Docs>
|
||||||
</Member>
|
</Member>
|
||||||
<Member MemberName="Finalize">
|
|
||||||
<MemberSignature Language="C#" Value="~VisualElement ();" />
|
|
||||||
<MemberSignature Language="ILAsm" Value=".method familyhidebysig virtual instance void Finalize() cil managed" />
|
|
||||||
<MemberType>Method</MemberType>
|
|
||||||
<AssemblyInfo>
|
|
||||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
|
||||||
</AssemblyInfo>
|
|
||||||
<ReturnValue>
|
|
||||||
<ReturnType>System.Void</ReturnType>
|
|
||||||
</ReturnValue>
|
|
||||||
<Parameters />
|
|
||||||
<Docs>
|
|
||||||
<summary>Finalizer for visual elements.</summary>
|
|
||||||
<remarks>To be added.</remarks>
|
|
||||||
</Docs>
|
|
||||||
</Member>
|
|
||||||
<Member MemberName="Focus">
|
<Member MemberName="Focus">
|
||||||
<MemberSignature Language="C#" Value="public bool Focus ();" />
|
<MemberSignature Language="C#" Value="public bool Focus ();" />
|
||||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance bool Focus() cil managed" />
|
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance bool Focus() cil managed" />
|
||||||
|
|
Загрузка…
Ссылка в новой задаче