ValueTaskCompletionSource<T>
public class ValueTaskCompletionSource<T> : ManualResetCompletionSource, IValueTaskSource<T>, IValueTaskSource, ISupplier<TimeSpan, CancellationToken, ValueTask>, IFunctional<Func<TimeSpan, CancellationToken, ValueTask>>, ISupplier<TimeSpan, CancellationToken, ValueTask<T>>, IFunctional<Func<TimeSpan, CancellationToken, ValueTask<T>>>
Represents the producer side of ValueTask<T>.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;
namespace DotNext.Threading.Tasks
{
[NullableContext(1)]
[Nullable(0)]
public class ValueTaskCompletionSource<[Nullable(2)] T> : ManualResetCompletionSource, IValueTaskSource<T>, IValueTaskSource
{
private sealed class LinkedTaskCompletionSource : TaskCompletionSource<T>
{
private IValueTaskSource<T> source;
private short version;
internal LinkedTaskCompletionSource(object state)
: base(state, TaskCreationOptions.None)
{
}
internal void LinkTo(IValueTaskSource<T> source, short version)
{
this.source = source;
this.version = version;
source.OnCompleted(delegate(object state) {
Unsafe.As<LinkedTaskCompletionSource>(state).OnCompleted();
}, this, version, ValueTaskSourceOnCompletedFlags.None);
}
private void OnCompleted()
{
if (source != null)
try {
TrySetResult(source.GetResult(version));
} catch (OperationCanceledException ex) {
TrySetCanceled(ex.CancellationToken);
} catch (Exception exception) {
TrySetException(exception);
}
source = null;
}
}
private Result<T> result;
public ValueTaskCompletionSource(bool runContinuationsAsynchronously = true)
: base(runContinuationsAsynchronously)
{
}
private static Result<T> FromCanceled(CancellationToken token)
{
return new Result<T>((Exception)new OperationCanceledException(token));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TrySetResult(T value)
{
return TrySetResult(null, value);
}
public unsafe bool TrySetResult([Nullable(2)] object completionData, T value)
{
return SetResult(completionData, null, (IntPtr)(void*), value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TrySetResult(short completionToken, T value)
{
return TrySetResult(null, completionToken, value);
}
public unsafe bool TrySetResult([Nullable(2)] object completionData, short completionToken, T value)
{
return SetResult(completionData, completionToken, (IntPtr)(void*), value);
}
public unsafe sealed override bool TrySetException([Nullable(2)] object completionData, Exception e)
{
return SetResult(completionData, null, (IntPtr)(void*), e);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TrySetException(short completionToken, Exception e)
{
return TrySetException(null, completionToken, e);
}
public unsafe bool TrySetException([Nullable(2)] object completionData, short completionToken, Exception e)
{
return SetResult(completionData, completionToken, (IntPtr)(void*), e);
}
[NullableContext(2)]
public unsafe sealed override bool TrySetCanceled(object completionData, CancellationToken token)
{
return SetResult(completionData, null, (IntPtr)(void*), token);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TrySetCanceled(short completionToken, CancellationToken token)
{
return TrySetCanceled(null, completionToken, token);
}
[NullableContext(2)]
public unsafe bool TrySetCanceled(object completionData, short completionToken, CancellationToken token)
{
return SetResult(completionData, completionToken, (IntPtr)(void*), token);
}
private protected sealed override bool CompleteAsTimedOut()
{
Result<T> val = OnTimeout();
return SetResult(ref val, null);
}
private protected sealed override bool CompleteAsCanceled(CancellationToken token)
{
Result<T> val = OnCanceled(token);
return SetResult(ref val, null);
}
private bool SetResult<TArg>(object completionData, short? completionToken, IntPtr func, TArg arg)
{
EnterLock();
bool flag = default(bool);
try {
flag = versionAndStatus.CanBeCompleted(completionToken);
if (!flag)
return flag;
Result<T> val = ;
if (!this.SetResult(ref val, completionData))
return flag;
} finally {
ExitLock();
}
Resume();
return flag;
}
private bool SetResult([In] [IsReadOnly] ref Result<T> result, object completionData = null)
{
this.result = result;
return SetResult(completionData);
}
internal bool TrySetResult(object completionData, short? completionToken, [In] [IsReadOnly] ref Result<T> result, out bool resumable)
{
EnterLock();
try {
bool flag;
resumable = ((flag = versionAndStatus.CanBeCompleted(completionToken)) && SetResult(ref result, completionData));
return flag;
} finally {
ExitLock();
}
}
protected override void Cleanup()
{
result = default(Result<T>);
}
[return: Nullable(new byte[] {
0,
1
})]
protected virtual Result<T> OnTimeout()
{
return new Result<T>((Exception)new TimeoutException());
}
[return: Nullable(new byte[] {
0,
1
})]
protected virtual Result<T> OnCanceled(CancellationToken token)
{
return new Result<T>((Exception)new OperationCanceledException(token));
}
[return: Nullable(new byte[] {
0,
1
})]
public ValueTask<T> CreateTask(TimeSpan timeout, CancellationToken token)
{
short? nullable = Activate(timeout, token);
if (!nullable.HasValue)
throw new InvalidOperationException(ExceptionMessages.InvalidSourceState);
short valueOrDefault = nullable.GetValueOrDefault();
return new ValueTask<T>(this, valueOrDefault);
}
ValueTask<T> Invoke(TimeSpan timeout, CancellationToken token)
{
return CreateTask(timeout, token);
}
ValueTask Invoke(TimeSpan timeout, CancellationToken token)
{
short? nullable = Activate(timeout, token);
if (!nullable.HasValue)
throw new InvalidOperationException(ExceptionMessages.InvalidSourceState);
short valueOrDefault = nullable.GetValueOrDefault();
return new ValueTask(this, valueOrDefault);
}
private T GetResult(short token)
{
Result<T> val = result;
versionAndStatus.Consume(token);
AfterConsumed();
return val.get_Value();
}
T IValueTaskSource<T>.GetResult(short token)
{
return GetResult(token);
}
void IValueTaskSource.GetResult(short token)
{
GetResult(token);
}
private ValueTaskSourceStatus GetStatus(short token)
{
Exception error = result.get_Error();
VersionAndStatus versionAndStatus = base.versionAndStatus.VolatileRead();
if (token != versionAndStatus.Version)
throw new InvalidOperationException(ExceptionMessages.InvalidSourceToken);
if (versionAndStatus.IsCompleted)
return (error == null) ? ValueTaskSourceStatus.Succeeded : ((!(error is OperationCanceledException)) ? ValueTaskSourceStatus.Faulted : ValueTaskSourceStatus.Canceled);
return ValueTaskSourceStatus.Pending;
}
ValueTaskSourceStatus IValueTaskSource<T>.GetStatus(short token)
{
return GetStatus(token);
}
ValueTaskSourceStatus IValueTaskSource.GetStatus(short token)
{
return GetStatus(token);
}
void IValueTaskSource<T>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
{
OnCompleted(continuation, state, token, flags);
}
void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
{
OnCompleted(continuation, state, token, flags);
}
public TaskCompletionSource<T> CreateLinkedTaskCompletionSource([Nullable(2)] object userData, TimeSpan timeout, CancellationToken token)
{
short? nullable = Activate(timeout, token);
if (!nullable.HasValue)
throw new InvalidOperationException(ExceptionMessages.InvalidSourceState);
short valueOrDefault = nullable.GetValueOrDefault();
LinkedTaskCompletionSource linkedTaskCompletionSource = new LinkedTaskCompletionSource(userData);
linkedTaskCompletionSource.LinkTo(this, valueOrDefault);
return linkedTaskCompletionSource;
}
}
}