diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
index 2fb8e84a2e..19fb54e125 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
@@ -322,36 +322,51 @@ namespace Avalonia.Rendering.SceneGraph
}
}
+ ///
+ /// Ensures that this node draw operations have been created and are mutable (in case we are using cloned operations).
+ ///
private void EnsureDrawOperationsCreated()
{
if (_drawOperations == null)
{
_drawOperations = new List>();
- _drawOperationsRefCounter = RefCountable.Create(Disposable.Create(DisposeDrawOperations));
+ _drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations));
_drawOperationsCloned = false;
}
else if (_drawOperationsCloned)
{
_drawOperations = new List>(_drawOperations.Select(op => op.Clone()));
_drawOperationsRefCounter.Dispose();
- _drawOperationsRefCounter = RefCountable.Create(Disposable.Create(DisposeDrawOperations));
+ _drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations));
_drawOperationsCloned = false;
}
}
- public bool Disposed { get; }
-
- public void Dispose()
+ ///
+ /// Creates disposable that will dispose all items in passed draw operations after being disposed.
+ /// It is crucial that we don't capture current instance
+ /// as draw operations can be cloned and may persist across subsequent scenes.
+ ///
+ /// Draw operations that need to be disposed.
+ /// Disposable for given draw operations.
+ private static IDisposable CreateDisposeDrawOperations(List> drawOperations)
{
- _drawOperationsRefCounter?.Dispose();
+ return Disposable.Create(() =>
+ {
+ foreach (var operation in drawOperations)
+ {
+ operation.Dispose();
+ }
+ });
}
- private void DisposeDrawOperations()
+ public bool Disposed { get; private set; }
+
+ public void Dispose()
{
- foreach (var operation in DrawOperations)
- {
- operation.Dispose();
- }
+ _drawOperationsRefCounter?.Dispose();
+
+ Disposed = true;
}
}
}