2019-12-04 18:57:18 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
2019-12-08 19:54:52 +01:00
|
|
|
|
namespace Swan.Threading {
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Acts as a <see cref="CancellationTokenSource"/> but with reusable tokens.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public sealed class CancellationTokenOwner : IDisposable {
|
|
|
|
|
private readonly Object _syncLock = new Object();
|
|
|
|
|
private Boolean _isDisposed;
|
|
|
|
|
private CancellationTokenSource _tokenSource = new CancellationTokenSource();
|
|
|
|
|
|
2019-12-04 18:57:18 +01:00
|
|
|
|
/// <summary>
|
2019-12-08 19:54:52 +01:00
|
|
|
|
/// Gets the token of the current.
|
2019-12-04 18:57:18 +01:00
|
|
|
|
/// </summary>
|
2019-12-08 19:54:52 +01:00
|
|
|
|
public CancellationToken Token {
|
|
|
|
|
get {
|
|
|
|
|
lock(this._syncLock) {
|
|
|
|
|
return this._isDisposed ? CancellationToken.None : this._tokenSource.Token;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Cancels the last referenced token and creates a new token source.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Cancel() {
|
|
|
|
|
lock(this._syncLock) {
|
|
|
|
|
if(this._isDisposed) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._tokenSource.Cancel();
|
|
|
|
|
this._tokenSource.Dispose();
|
|
|
|
|
this._tokenSource = new CancellationTokenSource();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public void Dispose() => this.Dispose(true);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Releases unmanaged and - optionally - managed resources.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
|
|
|
|
|
private void Dispose(Boolean disposing) {
|
|
|
|
|
lock(this._syncLock) {
|
|
|
|
|
if(this._isDisposed) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(disposing) {
|
|
|
|
|
this._tokenSource.Cancel();
|
|
|
|
|
this._tokenSource.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._isDisposed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-04 18:57:18 +01:00
|
|
|
|
}
|