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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with
23 additions and
12 deletions
-
src/Avalonia.Animation/DisposeAnimationInstanceSubject.cs
-
src/Avalonia.Base/PriorityLevel.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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -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(); |
|
|
|
|
|
|
|
|