public static System.Threading.Tasks.Task<long> GetStateMachine() { Action moveNext = null; var builder = new AsyncTaskMethodBuilder<long>(); int state = 0; var taskAwaiter = GetTaskResult().GetAwaiter(); moveNext = () => { switch (state) { case 0: { if (!taskAwaiter.IsCompleted) { state = 1; taskAwaiter.OnCompleted(moveNext); } break; } case 1: { builder.SetResult(taskAwaiter.GetResult()); break; } } }; moveNext(); return builder.Task; }
/// <summary> /// Initializes a new instance of the <see cref="AsyncTaskMethodBuilder"/> struct. /// </summary> private AsyncTaskMethodBuilder(TaskController taskManager) { this.TaskController = taskManager; this.MethodBuilder = default; this.IsCompleted = false; this.UseBuilder = false; }
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled<int>(cancellationToken); } _readAtmb = new AsyncTaskMethodBuilder<int>(); Task<int> t = _readAtmb.Task; _readArgs.SetBuffer(buffer, offset, count); if (!_socket.ReceiveAsync(_readArgs)) { ReadCompleted(null, _readArgs); } return t; }
public static IEnumerable<object[]> CanceledTasksAndExpectedCancellationExceptions() { var cts = new CancellationTokenSource(); var oce = new OperationCanceledException(cts.Token); // Scheduled Task Task<int> generic = Task.Run<int>(new Func<int>(() => { cts.Cancel(); throw oce; }), cts.Token); yield return new object[] { LineNumber(), generic, oce }; Task nonGeneric = generic; // WhenAll Task and Task<int> yield return new object[] { LineNumber(), Task.WhenAll(generic), oce }; yield return new object[] { LineNumber(), Task.WhenAll(generic, Task.FromResult(42)), oce }; yield return new object[] { LineNumber(), Task.WhenAll(Task.FromResult(42), generic), oce }; yield return new object[] { LineNumber(), Task.WhenAll(generic, generic, generic), oce }; yield return new object[] { LineNumber(), Task.WhenAll(nonGeneric), oce }; yield return new object[] { LineNumber(), Task.WhenAll(nonGeneric, Task.FromResult(42)), oce }; yield return new object[] { LineNumber(), Task.WhenAll(Task.FromResult(42), nonGeneric), oce }; yield return new object[] { LineNumber(), Task.WhenAll(nonGeneric, nonGeneric, nonGeneric), oce }; // Task.Run Task and Task<int> with unwrapping yield return new object[] { LineNumber(), Task.Run(() => generic), oce }; yield return new object[] { LineNumber(), Task.Run(() => nonGeneric), oce }; // A FromAsync Task and Task<int> yield return new object[] { LineNumber(), Task.Factory.FromAsync(generic, new Action<IAsyncResult>(ar => { throw oce; })), oce }; yield return new object[] { LineNumber(), Task<int>.Factory.FromAsync(nonGeneric, new Func<IAsyncResult, int>(ar => { throw oce; })), oce }; // AsyncTaskMethodBuilder var atmb = new AsyncTaskMethodBuilder(); atmb.SetException(oce); yield return new object[] { LineNumber(), atmb.Task, oce }; }
/// <summary> /// Initializes a new instance of the <see cref="AsyncTaskMethodBuilder"/> struct. /// </summary> private AsyncTaskMethodBuilder(CoyoteRuntime runtime) { this.Runtime = runtime; this.MethodBuilder = default; }
/// <summary> /// Initializes a new instance of the <see cref="AsyncTaskMethodBuilder"/> struct. /// </summary> private AsyncTaskMethodBuilder(TaskController taskController) { this.TaskController = taskController; this.MethodBuilder = default; }
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return Task.FromCanceled(cancellationToken); } _writeAtmb = new AsyncTaskMethodBuilder(); Task t = _writeAtmb.Task; _writeArgs.SetBuffer(buffer, offset, count); if (!_socket.SendAsync(_writeArgs)) { // TODO: #4900 This path should be hit very frequently (sends should very frequently simply // write into the kernel's send buffer), but it's practically never getting hit due to the current // System.Net.Sockets.dll implementation that always completing asynchronously on success :( // If that doesn't get fixed, we should try to come up with some alternative here. This is // an important path, in part as it means the caller will complete awaits synchronously rather // than spending the costs associated with yielding in each async method up the call chain. // (This applies to ReadAsync as well, but typically to a much less extent.) WriteCompleted(null, _writeArgs); } return t; }
public static void RunAsyncAdditionalBehaviorsTests() { { var atmb = new AsyncTaskMethodBuilder(); var t1 = atmb.Task; var t2 = atmb.Task; Assert.True(t1 != null, " > FAILURE. Task should have been initialized."); Assert.True(t2 != null, " > FAILURE. Task should have been initialized."); Assert.True(t1 == t2, " > FAILURE. Task should be cached once initialized."); } { var atmb = new AsyncTaskMethodBuilder<int>(); var t1 = atmb.Task; var t2 = atmb.Task; Assert.True(t1 != null, " > FAILURE. Task should have been initialized."); Assert.True(t2 != null, " > FAILURE. Task should have been initialized."); Assert.True(t1 == t2, " > FAILURE. Task should be cached once initialized."); } }
public static void RunAsyncMethodBuilderTests_NegativeTests() { // Incorrect usage for AsyncVoidMethodBuilder { var atmb = new AsyncTaskMethodBuilder(); Assert.Throws<ArgumentNullException>( () => { atmb.SetException(null); }); } // Incorrect usage for AsyncTaskMethodBuilder { var avmb = AsyncVoidMethodBuilder.Create(); Assert.Throws<ArgumentNullException>( () => { avmb.SetException(null); }); } // Creating a task builder, building it, completing it successfully, and making sure it can't be reset { var atmb = AsyncTaskMethodBuilder.Create(); atmb.SetResult(); Assert.Throws<InvalidOperationException>( () => { atmb.SetResult(); }); Assert.Throws<InvalidOperationException>( () => { atmb.SetException(new Exception()); }); } // Incorrect usage for AsyncTaskMethodBuilder<T> { var atmb = new AsyncTaskMethodBuilder<int>(); Assert.Throws<ArgumentNullException>( () => { atmb.SetException(null); }); } // Creating a task builder <T>, building it, completing it successfully, and making sure it can't be reset { var atmb = AsyncTaskMethodBuilder<int>.Create(); atmb.SetResult(43); Assert.Throws<InvalidOperationException>( () => { atmb.SetResult(44); }); Assert.Throws<InvalidOperationException>( () => { atmb.SetException(new Exception()); }); } }