Browse Source

Merge pull request #3062 from MarchingCube/fix-binding-double-dispose

Fix double dispose of bindings caused by animations
pull/3065/head
Jumar Macato 7 years ago
committed by GitHub
parent
commit
98336c696b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      src/Avalonia.Animation/DisposeAnimationInstanceSubject.cs
  2. 19
      src/Avalonia.Base/PriorityLevel.cs

16
src/Avalonia.Animation/DisposeAnimationInstanceSubject.cs

@ -2,14 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using Avalonia.Animation.Animators;
using Avalonia.Animation.Utils;
using Avalonia.Collections;
using Avalonia.Data;
using Avalonia.Reactive;
namespace Avalonia.Animation
{
@ -46,6 +39,7 @@ namespace Avalonia.Animation
public void OnError(Exception error)
{
_lastInstance?.Dispose();
_lastInstance = null;
}
void IObserver<bool>.OnNext(bool matchVal)
@ -53,12 +47,18 @@ namespace Avalonia.Animation
if (matchVal != _lastMatch)
{
_lastInstance?.Dispose();
if (matchVal)
{
_lastInstance = _animator.Run(_animation, _control, _clock, _onComplete);
}
else
{
_lastInstance = null;
}
_lastMatch = matchVal;
}
}
}
}
}

19
src/Avalonia.Base/PriorityLevel.cs

@ -3,7 +3,8 @@
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Diagnostics;
using System.Threading;
using Avalonia.Data;
namespace Avalonia
@ -181,9 +182,9 @@ namespace Avalonia
private sealed class RemoveBindingDisposable : IDisposable
{
private readonly LinkedListNode<PriorityBindingEntry> _binding;
private readonly LinkedList<PriorityBindingEntry> _bindings;
private readonly PriorityLevel _priorityLevel;
private LinkedListNode<PriorityBindingEntry> _binding;
public RemoveBindingDisposable(
LinkedListNode<PriorityBindingEntry> binding,
@ -197,11 +198,21 @@ namespace Avalonia
public void Dispose()
{
PriorityBindingEntry entry = _binding.Value;
LinkedListNode<PriorityBindingEntry> binding = Interlocked.Exchange(ref _binding, null);
if (binding == null)
{
// Some system is trying to remove binding twice.
Debug.Assert(false);
return;
}
PriorityBindingEntry entry = binding.Value;
if (!entry.HasCompleted)
{
_bindings.Remove(_binding);
_bindings.Remove(binding);
entry.Dispose();

Loading…
Cancel
Save