|
|
@ -11,7 +11,7 @@ namespace Avalonia.Threading; |
|
|
public class DispatcherOperation |
|
|
public class DispatcherOperation |
|
|
{ |
|
|
{ |
|
|
protected readonly bool ThrowOnUiThread; |
|
|
protected readonly bool ThrowOnUiThread; |
|
|
public DispatcherOperationStatus Status { get; protected set; } |
|
|
public DispatcherOperationStatus Status { get; internal set; } |
|
|
public Dispatcher Dispatcher { get; } |
|
|
public Dispatcher Dispatcher { get; } |
|
|
|
|
|
|
|
|
public DispatcherPriority Priority |
|
|
public DispatcherPriority Priority |
|
|
@ -115,13 +115,13 @@ public class DispatcherOperation |
|
|
|
|
|
|
|
|
public bool Abort() |
|
|
public bool Abort() |
|
|
{ |
|
|
{ |
|
|
lock (Dispatcher.InstanceLock) |
|
|
if (Dispatcher.Abort(this)) |
|
|
{ |
|
|
{ |
|
|
if (Status != DispatcherOperationStatus.Pending) |
|
|
CallAbortCallbacks(); |
|
|
return false; |
|
|
|
|
|
Dispatcher.Abort(this); |
|
|
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
@ -254,20 +254,15 @@ public class DispatcherOperation |
|
|
return GetTask().GetAwaiter(); |
|
|
return GetTask().GetAwaiter(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
internal void DoAbort() |
|
|
internal void CallAbortCallbacks() |
|
|
{ |
|
|
{ |
|
|
Status = DispatcherOperationStatus.Aborted; |
|
|
|
|
|
AbortTask(); |
|
|
AbortTask(); |
|
|
_aborted?.Invoke(this, EventArgs.Empty); |
|
|
_aborted?.Invoke(this, EventArgs.Empty); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
internal void Execute() |
|
|
internal void Execute() |
|
|
{ |
|
|
{ |
|
|
lock (Dispatcher.InstanceLock) |
|
|
Debug.Assert(Status == DispatcherOperationStatus.Executing); |
|
|
{ |
|
|
|
|
|
Status = DispatcherOperationStatus.Executing; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try |
|
|
try |
|
|
{ |
|
|
{ |
|
|
using (AvaloniaSynchronizationContext.Ensure(Dispatcher, Priority)) |
|
|
using (AvaloniaSynchronizationContext.Ensure(Dispatcher, Priority)) |
|
|
@ -311,7 +306,19 @@ public class DispatcherOperation |
|
|
|
|
|
|
|
|
internal virtual object? GetResult() => null; |
|
|
internal virtual object? GetResult() => null; |
|
|
|
|
|
|
|
|
protected virtual void AbortTask() => (TaskSource as TaskCompletionSource<object?>)?.SetCanceled(); |
|
|
protected virtual void AbortTask() |
|
|
|
|
|
{ |
|
|
|
|
|
object? taskSource; |
|
|
|
|
|
lock (Dispatcher.InstanceLock) |
|
|
|
|
|
{ |
|
|
|
|
|
Debug.Assert(Status == DispatcherOperationStatus.Aborted); |
|
|
|
|
|
// There is no way for TaskSource to become not-null after being null with aborted tasks,
|
|
|
|
|
|
// so it's safe to save it here and use after exiting the lock
|
|
|
|
|
|
taskSource = TaskSource; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
(taskSource as TaskCompletionSource<object?>)?.SetCanceled(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private static CancellationToken CreateCancelledToken() |
|
|
private static CancellationToken CreateCancelledToken() |
|
|
{ |
|
|
{ |
|
|
|