Last active
October 5, 2018 16:42
-
-
Save jcouv/ae7800985e3a8700bb84c6650d25bb69 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Reflection; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.ExceptionServices; | |
using System.Threading.Tasks; | |
using System.Threading.Tasks.Sources; | |
[assembly: CompilationRelaxations(8)] | |
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] | |
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] | |
[assembly: AssemblyVersion("0.0.0.0")] | |
public class C | |
{ | |
[CompilerGenerated] | |
private sealed class <M>d__0 : IAsyncEnumerable<int>, IAsyncEnumerator<int>, IAsyncDisposable, IValueTaskSource<bool>, IStrongBox<ManualResetValueTaskSourceLogic<bool>>, IAsyncStateMachine | |
{ | |
public int <>1__state; | |
public AsyncIteratorMethodBuilder <>t__builder; // <-- new builder type | |
public ManualResetValueTaskSourceLogic<bool> <>v__promiseOfValueOrEnd; | |
private int <>2__current; | |
private TaskAwaiter <>u__1; | |
int IAsyncEnumerator<int>.Current | |
{ | |
[DebuggerHidden] | |
get | |
{ | |
return <>2__current; | |
} | |
} | |
ManualResetValueTaskSourceLogic<bool> IStrongBox<ManualResetValueTaskSourceLogic<bool>>.Value | |
{ | |
[DebuggerHidden] | |
get | |
{ | |
return ref <>v__promiseOfValueOrEnd; | |
} | |
} | |
private void MoveNext() | |
{ | |
int num = <>1__state; | |
try | |
{ | |
TaskAwaiter awaiter; | |
switch (num) | |
{ | |
case 1: | |
break; | |
default: | |
awaiter = Task.CompletedTask.GetAwaiter(); | |
if (!awaiter.IsCompleted) | |
{ | |
num = (<>1__state = 0); | |
<>u__1 = awaiter; | |
<M>d__0 stateMachine = this; | |
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); // <-- | |
return; | |
} | |
goto IL_006b; | |
case 0: | |
{ | |
awaiter = <>u__1; | |
<>u__1 = default(TaskAwaiter); | |
num = (<>1__state = -1); | |
goto IL_006b; | |
} | |
IL_006b: | |
awaiter.GetResult(); | |
<>2__current = 4; | |
<>1__state = 1; | |
<>v__promiseOfValueOrEnd.SetResult(result: true); | |
return; | |
} | |
} | |
catch (Exception exception) | |
{ | |
<>1__state = -2; | |
<>v__promiseOfValueOrEnd.SetException(exception); | |
return; | |
} | |
<>1__state = -2; | |
<>v__promiseOfValueOrEnd.SetResult(result: false); | |
} | |
void IAsyncStateMachine.MoveNext() | |
{ | |
//ILSpy generated this explicit interface implementation from .override directive in MoveNext | |
this.MoveNext(); | |
} | |
[DebuggerHidden] | |
private void SetStateMachine(IAsyncStateMachine stateMachine) | |
{ | |
} | |
void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) | |
{ | |
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine | |
this.SetStateMachine(stateMachine); | |
} | |
[DebuggerHidden] | |
IAsyncEnumerator<int> IAsyncEnumerable<int>.GetAsyncEnumerator() | |
{ | |
return this; | |
} | |
[DebuggerHidden] | |
ValueTask<bool> IAsyncEnumerator<int>.MoveNextAsync() | |
{ | |
if (<>1__state == -2) | |
{ | |
return default(ValueTask<bool>); | |
} | |
<>v__promiseOfValueOrEnd.Reset(); | |
<M>d__0 stateMachine = this; | |
<>t__builder.MoveNext(ref stateMachine); // <-- | |
return new ValueTask<bool>(this, <>v__promiseOfValueOrEnd.Version); | |
} | |
[DebuggerHidden] | |
bool IValueTaskSource<bool>.GetResult(short token) | |
{ | |
return <>v__promiseOfValueOrEnd.GetResult(token); | |
} | |
[DebuggerHidden] | |
ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) | |
{ | |
return <>v__promiseOfValueOrEnd.GetStatus(token); | |
} | |
[DebuggerHidden] | |
void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) | |
{ | |
<>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); | |
} | |
[DebuggerHidden] | |
ValueTask IAsyncDisposable.DisposeAsync() | |
{ | |
<>t__builder.Complete(); // <-- | |
<>v__promiseOfValueOrEnd.Reset(); | |
<>1__state = -1; | |
return default(ValueTask); | |
} | |
} | |
[AsyncStateMachine(typeof(<M>d__0))] | |
[IteratorStateMachine(typeof(<M>d__0))] | |
public static IAsyncEnumerable<int> M() | |
{ | |
<M>d__0 <M>d__ = new <M>d__0(); | |
<M>d__.<>t__builder = AsyncIteratorMethodBuilder.Create(); // <-- | |
<M>d__.<>1__state = -1; | |
<M>d__.<>v__promiseOfValueOrEnd = new ManualResetValueTaskSourceLogic<bool>(<M>d__); | |
return <M>d__; | |
} | |
} | |
namespace System | |
{ | |
public interface IAsyncDisposable | |
{ | |
ValueTask DisposeAsync(); | |
} | |
} | |
namespace System.Threading.Tasks | |
{ | |
public struct ManualResetValueTaskSourceLogic<TResult> | |
{ | |
private static readonly Action<object> s_sentinel = delegate | |
{ | |
throw new InvalidOperationException(); | |
}; | |
private readonly IStrongBox<ManualResetValueTaskSourceLogic<TResult>> _parent; | |
private Action<object> _continuation; | |
private object _continuationState; | |
private object _capturedContext; | |
private ExecutionContext _executionContext; | |
private bool _completed; | |
private TResult _result; | |
private ExceptionDispatchInfo _error; | |
private short _version; | |
public short Version => _version; | |
public ManualResetValueTaskSourceLogic(IStrongBox<ManualResetValueTaskSourceLogic<TResult>> parent) | |
{ | |
if (parent == null) | |
{ | |
throw new ArgumentNullException("parent"); | |
} | |
_parent = parent; | |
_continuation = null; | |
_continuationState = null; | |
_capturedContext = null; | |
_executionContext = null; | |
_completed = false; | |
_result = default(TResult); | |
_error = null; | |
_version = 0; | |
} | |
private void ValidateToken(short token) | |
{ | |
if (token != _version) | |
{ | |
throw new InvalidOperationException(); | |
} | |
} | |
public ValueTaskSourceStatus GetStatus(short token) | |
{ | |
ValidateToken(token); | |
return _completed ? ((_error == null) ? ValueTaskSourceStatus.Succeeded : ((_error.SourceException is OperationCanceledException) ? ValueTaskSourceStatus.Canceled : ValueTaskSourceStatus.Faulted)) : ValueTaskSourceStatus.Pending; | |
} | |
public TResult GetResult(short token) | |
{ | |
ValidateToken(token); | |
if (!_completed) | |
{ | |
throw new InvalidOperationException(); | |
} | |
_error?.Throw(); | |
return _result; | |
} | |
public void Reset() | |
{ | |
_version++; | |
_completed = false; | |
_continuation = null; | |
_continuationState = null; | |
_result = default(TResult); | |
_error = null; | |
_executionContext = null; | |
_capturedContext = null; | |
} | |
public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) | |
{ | |
if (continuation == null) | |
{ | |
throw new ArgumentNullException("continuation"); | |
} | |
ValidateToken(token); | |
if ((flags & ValueTaskSourceOnCompletedFlags.FlowExecutionContext) != 0) | |
{ | |
_executionContext = ExecutionContext.Capture(); | |
} | |
if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) | |
{ | |
SynchronizationContext current = SynchronizationContext.Current; | |
if (current != null && current.GetType() != typeof(SynchronizationContext)) | |
{ | |
_capturedContext = current; | |
} | |
else | |
{ | |
TaskScheduler current2 = TaskScheduler.Current; | |
if (current2 != TaskScheduler.Default) | |
{ | |
_capturedContext = current2; | |
} | |
} | |
} | |
_continuationState = state; | |
if (Interlocked.CompareExchange(ref _continuation, continuation, null) != null) | |
{ | |
_executionContext = null; | |
object capturedContext = _capturedContext; | |
_capturedContext = null; | |
object obj = capturedContext; | |
object obj2 = obj; | |
if (obj2 != null) | |
{ | |
SynchronizationContext synchronizationContext; | |
if ((synchronizationContext = (obj2 as SynchronizationContext)) == null) | |
{ | |
TaskScheduler taskScheduler; | |
if ((taskScheduler = (obj2 as TaskScheduler)) != null) | |
{ | |
TaskScheduler scheduler = taskScheduler; | |
Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, scheduler); | |
} | |
} | |
else | |
{ | |
SynchronizationContext synchronizationContext2 = synchronizationContext; | |
synchronizationContext2.Post(delegate(object s) | |
{ | |
Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s; | |
tuple.Item1(tuple.Item2); | |
}, Tuple.Create(continuation, state)); | |
} | |
} | |
else | |
{ | |
Task.Factory.StartNew(continuation, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); | |
} | |
} | |
} | |
public void SetResult(TResult result) | |
{ | |
_result = result; | |
SignalCompletion(); | |
} | |
public void SetException(Exception error) | |
{ | |
_error = ExceptionDispatchInfo.Capture(error); | |
SignalCompletion(); | |
} | |
private void SignalCompletion() | |
{ | |
if (_completed) | |
{ | |
throw new InvalidOperationException(); | |
} | |
_completed = true; | |
if (Interlocked.CompareExchange(ref _continuation, s_sentinel, null) != null) | |
{ | |
if (_executionContext != null) | |
{ | |
ExecutionContext executionContext = _executionContext; | |
ContextCallback callback = delegate(object s) | |
{ | |
((IStrongBox<ManualResetValueTaskSourceLogic<TResult>>)s).Value.InvokeContinuation(); | |
}; | |
IStrongBox<ManualResetValueTaskSourceLogic<TResult>> parent = _parent; | |
if (parent == null) | |
{ | |
throw new InvalidOperationException(); | |
} | |
ExecutionContext.Run(executionContext, callback, parent); | |
} | |
else | |
{ | |
InvokeContinuation(); | |
} | |
} | |
} | |
private void InvokeContinuation() | |
{ | |
object capturedContext = _capturedContext; | |
_capturedContext = null; | |
object obj = capturedContext; | |
object obj2 = obj; | |
if (obj2 != null) | |
{ | |
SynchronizationContext synchronizationContext; | |
if ((synchronizationContext = (obj2 as SynchronizationContext)) == null) | |
{ | |
TaskScheduler taskScheduler; | |
if ((taskScheduler = (obj2 as TaskScheduler)) != null) | |
{ | |
TaskScheduler scheduler = taskScheduler; | |
Task.Factory.StartNew(_continuation, _continuationState, CancellationToken.None, TaskCreationOptions.DenyChildAttach, scheduler); | |
} | |
} | |
else | |
{ | |
SynchronizationContext synchronizationContext2 = synchronizationContext; | |
SynchronizationContext synchronizationContext3 = synchronizationContext2; | |
SendOrPostCallback d = delegate(object s) | |
{ | |
ref ManualResetValueTaskSourceLogic<TResult> value = ref ((IStrongBox<ManualResetValueTaskSourceLogic<TResult>>)s).Value; | |
value._continuation(value._continuationState); | |
}; | |
IStrongBox<ManualResetValueTaskSourceLogic<TResult>> parent = _parent; | |
if (parent == null) | |
{ | |
throw new InvalidOperationException(); | |
} | |
synchronizationContext3.Post(d, parent); | |
} | |
} | |
else | |
{ | |
_continuation(_continuationState); | |
} | |
} | |
} | |
} | |
namespace System.Runtime.CompilerServices | |
{ | |
public interface IStrongBox<T> | |
{ | |
ref T Value | |
{ | |
get; | |
} | |
} | |
} | |
namespace System.Collections.Generic | |
{ | |
public interface IAsyncEnumerable<out T> | |
{ | |
IAsyncEnumerator<T> GetAsyncEnumerator(); | |
} | |
public interface IAsyncEnumerator<out T> : IAsyncDisposable | |
{ | |
T Current | |
{ | |
get; | |
} | |
ValueTask<bool> MoveNextAsync(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment