You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/Async/Internal/CompletionSourceAwaiterFact...

64 lines
2.1 KiB

5 years ago
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace ZeroLevel.Services.Async.Internal
{
internal struct CompletionSourceAwaiterFactory<T>
: IAwaiterFactory<T>, IEquatable<CompletionSourceAwaiterFactory<T>>
{
private readonly CancellationToken _cancellationToken;
public CompletionSourceAwaiterFactory(CancellationToken cancellationToken)
{
_cancellationToken = cancellationToken;
}
public IAwaiter<T> CreateAwaiter() => new CompletionSourceAwaiter(_cancellationToken);
/// <summary>
/// A simple <see cref="TaskCompletionSource{T}"/> wrapper that implements <see cref="IAwaiter{T}"/>.
/// </summary>
private class CompletionSourceAwaiter : IAwaiter<T>
{
private readonly TaskCompletionSource<T> _completionSource;
private readonly CancellationTokenRegistration _registration;
public CompletionSourceAwaiter(CancellationToken cancellationToken)
{
_completionSource = new TaskCompletionSource<T>();
Task = new ValueTask<T>(_completionSource.Task.WithYield());
_registration = cancellationToken.Register(
state =>
{
TaskCompletionSource<T> awaiter = state as TaskCompletionSource<T>;
awaiter.TrySetCanceled();
},
_completionSource,
useSynchronizationContext: false);
}
public bool TrySetResult(T result)
{
_registration.Dispose();
return _completionSource.TrySetResult(result);
}
public ValueTask<T> Task { get; }
}
#region IEquatable<CompletionSourceAwaiterFactory<T>>
public override int GetHashCode() => EqualityComparer<CancellationToken>.Default.GetHashCode(_cancellationToken);
public bool Equals(CompletionSourceAwaiterFactory<T> other) => _cancellationToken == other._cancellationToken;
public override bool Equals(object obj) => obj is CompletionSourceAwaiterFactory<T> && Equals((CompletionSourceAwaiterFactory<T>)obj);
public static bool operator ==(CompletionSourceAwaiterFactory<T> x, CompletionSourceAwaiterFactory<T> y) => x.Equals(y);
public static bool operator !=(CompletionSourceAwaiterFactory<T> x, CompletionSourceAwaiterFactory<T> y) => !x.Equals(y);
#endregion
}
}

Powered by TurnKey Linux.