|
|
|
@ -17,29 +17,29 @@ namespace ICSharpCode.AvalonEdit
@@ -17,29 +17,29 @@ namespace ICSharpCode.AvalonEdit
|
|
|
|
|
public class WeakReferenceTests |
|
|
|
|
{ |
|
|
|
|
[Test] |
|
|
|
|
public void GCCallbackTest() |
|
|
|
|
public void TextViewCanBeCollectedTest() |
|
|
|
|
{ |
|
|
|
|
bool collectedTextView = false; |
|
|
|
|
TextView textView = new TextViewWithGCCallback(delegate { collectedTextView = true; }); |
|
|
|
|
TextView textView = new TextView(); |
|
|
|
|
WeakReference wr = new WeakReference(textView); |
|
|
|
|
textView = null; |
|
|
|
|
GarbageCollect(); |
|
|
|
|
Assert.IsTrue(collectedTextView); |
|
|
|
|
Assert.IsFalse(wr.IsAlive); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void DocumentDoesNotHoldReferenceToTextView() |
|
|
|
|
{ |
|
|
|
|
bool collectedTextView = false; |
|
|
|
|
TextDocument textDocument = new TextDocument(); |
|
|
|
|
Assert.AreEqual(0, textDocument.LineTrackers.Count); |
|
|
|
|
|
|
|
|
|
TextView textView = new TextViewWithGCCallback(delegate { collectedTextView = true; }); |
|
|
|
|
TextView textView = new TextView(); |
|
|
|
|
WeakReference wr = new WeakReference(textView); |
|
|
|
|
textView.Document = textDocument; |
|
|
|
|
Assert.AreEqual(1, textDocument.LineTrackers.Count); |
|
|
|
|
textView = null; |
|
|
|
|
|
|
|
|
|
GarbageCollect(); |
|
|
|
|
Assert.IsTrue(collectedTextView); |
|
|
|
|
Assert.IsFalse(wr.IsAlive); |
|
|
|
|
// document cannot immediately clear the line tracker
|
|
|
|
|
Assert.AreEqual(1, textDocument.LineTrackers.Count); |
|
|
|
|
|
|
|
|
@ -52,15 +52,15 @@ namespace ICSharpCode.AvalonEdit
@@ -52,15 +52,15 @@ namespace ICSharpCode.AvalonEdit
|
|
|
|
|
[Ignore] |
|
|
|
|
public void DocumentDoesNotHoldReferenceToTextArea() |
|
|
|
|
{ |
|
|
|
|
bool collectedTextArea = false; |
|
|
|
|
TextDocument textDocument = new TextDocument(); |
|
|
|
|
|
|
|
|
|
TextArea textArea = new TextAreaWithGCCallback(delegate { collectedTextArea = true; }); |
|
|
|
|
TextArea textArea = new TextArea(); |
|
|
|
|
WeakReference wr = new WeakReference(textArea); |
|
|
|
|
textArea.Document = textDocument; |
|
|
|
|
textArea = null; |
|
|
|
|
|
|
|
|
|
GarbageCollect(); |
|
|
|
|
Assert.IsTrue(collectedTextArea); |
|
|
|
|
Assert.IsFalse(wr.IsAlive); |
|
|
|
|
GC.KeepAlive(textDocument); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -68,40 +68,40 @@ namespace ICSharpCode.AvalonEdit
@@ -68,40 +68,40 @@ namespace ICSharpCode.AvalonEdit
|
|
|
|
|
[Ignore] |
|
|
|
|
public void DocumentDoesNotHoldReferenceToTextEditor() |
|
|
|
|
{ |
|
|
|
|
bool collectedTextEditor = false; |
|
|
|
|
TextDocument textDocument = new TextDocument(); |
|
|
|
|
|
|
|
|
|
TextEditor textEditor = new TextEditorWithGCCallback(delegate { collectedTextEditor = true; }); |
|
|
|
|
TextEditor textEditor = new TextEditor(); |
|
|
|
|
WeakReference wr = new WeakReference(textEditor); |
|
|
|
|
textEditor.Document = textDocument; |
|
|
|
|
textEditor = null; |
|
|
|
|
|
|
|
|
|
GarbageCollect(); |
|
|
|
|
Assert.IsTrue(collectedTextEditor); |
|
|
|
|
Assert.IsFalse(wr.IsAlive); |
|
|
|
|
GC.KeepAlive(textDocument); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[Test] |
|
|
|
|
public void DocumentDoesNotHoldReferenceToLineMargin() |
|
|
|
|
{ |
|
|
|
|
bool collectedTextView = false; |
|
|
|
|
TextDocument textDocument = new TextDocument(); |
|
|
|
|
|
|
|
|
|
DocumentDoesNotHoldReferenceToLineMargin_CreateMargin(textDocument, delegate { collectedTextView = true; }); |
|
|
|
|
WeakReference wr = DocumentDoesNotHoldReferenceToLineMargin_CreateMargin(textDocument); |
|
|
|
|
|
|
|
|
|
GarbageCollect(); |
|
|
|
|
Assert.IsTrue(collectedTextView); |
|
|
|
|
Assert.IsFalse(wr.IsAlive); |
|
|
|
|
GC.KeepAlive(textDocument); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// using a method to ensure the local variables can be garbage collected after the method returns
|
|
|
|
|
void DocumentDoesNotHoldReferenceToLineMargin_CreateMargin(TextDocument textDocument, Action finalizeAction) |
|
|
|
|
WeakReference DocumentDoesNotHoldReferenceToLineMargin_CreateMargin(TextDocument textDocument) |
|
|
|
|
{ |
|
|
|
|
TextView textView = new TextViewWithGCCallback(finalizeAction) { |
|
|
|
|
TextView textView = new TextView() { |
|
|
|
|
Document = textDocument |
|
|
|
|
}; |
|
|
|
|
LineNumberMargin margin = new LineNumberMargin() { |
|
|
|
|
TextView = textView |
|
|
|
|
}; |
|
|
|
|
return new WeakReference(textView); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void GarbageCollect() |
|
|
|
@ -110,50 +110,5 @@ namespace ICSharpCode.AvalonEdit
@@ -110,50 +110,5 @@ namespace ICSharpCode.AvalonEdit
|
|
|
|
|
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); |
|
|
|
|
GC.WaitForPendingFinalizers(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sealed class TextViewWithGCCallback : TextView |
|
|
|
|
{ |
|
|
|
|
Action onFinalize; |
|
|
|
|
|
|
|
|
|
public TextViewWithGCCallback(Action onFinalize) |
|
|
|
|
{ |
|
|
|
|
this.onFinalize = onFinalize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~TextViewWithGCCallback() |
|
|
|
|
{ |
|
|
|
|
onFinalize(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sealed class TextAreaWithGCCallback : TextArea |
|
|
|
|
{ |
|
|
|
|
Action onFinalize; |
|
|
|
|
|
|
|
|
|
public TextAreaWithGCCallback(Action onFinalize) |
|
|
|
|
{ |
|
|
|
|
this.onFinalize = onFinalize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~TextAreaWithGCCallback() |
|
|
|
|
{ |
|
|
|
|
onFinalize(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sealed class TextEditorWithGCCallback : TextEditor |
|
|
|
|
{ |
|
|
|
|
Action onFinalize; |
|
|
|
|
|
|
|
|
|
public TextEditorWithGCCallback(Action onFinalize) |
|
|
|
|
{ |
|
|
|
|
this.onFinalize = onFinalize; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
~TextEditorWithGCCallback() |
|
|
|
|
{ |
|
|
|
|
onFinalize(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|