|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace BasicWebSite.Controllers;
public class AsyncActionsController : Controller
{
const int SimulateDelayMilliseconds = 20;
public override void OnActionExecuted(ActionExecutedContext context)
{
// So that tests can observe we're following the proper flow after an exception, surface a
// message saying what the exception was.
if (context.Exception != null)
{
context.Result = Content($"Action exception message: {context.Exception.Message}");
context.ExceptionHandled = true;
}
}
public async Task<IActionResult> ActionWithSuffixAsync()
{
await Task.Yield();
return Ok();
}
public Task<IActionResult> ActionReturningViewAsync()
{
return Task.FromResult<IActionResult>(View());
}
public async void AsyncVoidAction()
{
await Task.Delay(SimulateDelayMilliseconds);
}
public Task TaskAction()
{
return Task.Delay(SimulateDelayMilliseconds);
}
public async Task TaskExceptionAction()
{
await Task.Delay(SimulateDelayMilliseconds);
throw new CustomException();
}
public async Task<Message> TaskOfObjectAction(string message)
{
await Task.Delay(SimulateDelayMilliseconds);
return new Message { Text = message };
}
public async Task<Message> TaskOfObjectExceptionAction(string message)
{
await Task.Delay(SimulateDelayMilliseconds);
throw new CustomException();
}
public async Task<IActionResult> TaskOfIActionResultAction(string message)
{
await Task.Delay(SimulateDelayMilliseconds);
return Content(message);
}
public async Task<IActionResult> TaskOfIActionResultExceptionAction(string message)
{
await Task.Delay(SimulateDelayMilliseconds);
throw new CustomException();
}
public async Task<ContentResult> TaskOfContentResultAction(string message)
{
await Task.Delay(SimulateDelayMilliseconds);
return Content(message);
}
public async Task<ContentResult> TaskOfContentResultExceptionAction(string message)
{
await Task.Delay(SimulateDelayMilliseconds);
throw new CustomException();
}
public ValueTask<Message> PreCompletedValueTaskOfObjectAction(string message)
{
return new ValueTask<Message>(new Message { Text = message });
}
public ValueTask<Message> PreCompletedValueTaskOfObjectExceptionAction(string message)
{
throw new CustomException();
}
public ValueTask<IActionResult> PreCompletedValueTaskOfIActionResultAction(string message)
{
return new ValueTask<IActionResult>(Content(message));
}
public ValueTask<IActionResult> PreCompletedValueTaskOfIActionResultExceptionAction(string message)
{
throw new CustomException();
}
public ValueTask<ContentResult> PreCompletedValueTaskOfContentResultAction(string message)
{
return new ValueTask<ContentResult>(Content(message));
}
public ValueTask<ContentResult> PreCompletedValueTaskOfContentResultExceptionAction(string message)
{
throw new CustomException();
}
public CustomAwaitable CustomAwaitableVoidAction()
{
return new CustomAwaitable(SimulateDelayMilliseconds);
}
public CustomAwaitable CustomAwaitableVoidExceptionAction()
{
throw new CustomException();
}
public CustomAwaitable<Message> CustomAwaitableOfObjectAction(string message)
{
return new CustomAwaitable<Message>(
SimulateDelayMilliseconds,
new Message { Text = message });
}
public CustomAwaitable<Message> CustomAwaitableOfObjectExceptionAction(string message)
{
throw new CustomException();
}
public CustomAwaitable<IActionResult> CustomAwaitableOfIActionResultAction(string message)
{
return new CustomAwaitable<IActionResult>(SimulateDelayMilliseconds, Content(message));
}
public CustomAwaitable<IActionResult> CustomAwaitableOfIActionResultExceptionAction(string message)
{
throw new CustomException();
}
public CustomAwaitable<ContentResult> CustomAwaitableOfContentResultAction(string message)
{
return new CustomAwaitable<ContentResult>(SimulateDelayMilliseconds, Content(message));
}
public CustomAwaitable<ContentResult> CustomAwaitableOfContentResultExceptionAction(string message)
{
throw new CustomException();
}
public class Message
{
public string Text { get; set; }
}
public class CustomAwaitable
{
protected readonly int _simulateDelayMilliseconds;
public CustomAwaitable(int simulateDelayMilliseconds)
{
_simulateDelayMilliseconds = simulateDelayMilliseconds;
}
public CustomAwaiter GetAwaiter()
{
return new CustomAwaiter(_simulateDelayMilliseconds);
}
}
public class CustomAwaitable<T> : CustomAwaitable
{
private readonly T _result;
public CustomAwaitable(int simulateDelayMilliseconds, T result)
: base(simulateDelayMilliseconds)
{
_result = result;
}
public new CustomAwaiter<T> GetAwaiter()
{
return new CustomAwaiter<T>(_simulateDelayMilliseconds, _result);
}
}
public class CustomAwaiter : INotifyCompletion
{
private readonly IList<Action> _continuations = new List<Action>();
public CustomAwaiter(int simulateDelayMilliseconds)
{
Task.Factory.StartNew(() =>
{
Thread.Sleep(simulateDelayMilliseconds);
lock (_continuations)
{
IsCompleted = true;
foreach (var continuation in _continuations)
{
continuation();
}
_continuations.Clear();
}
});
}
public bool IsCompleted { get; private set; }
public void OnCompleted(Action continuation)
{
lock (_continuations)
{
if (IsCompleted)
{
continuation();
}
else
{
_continuations.Add(continuation);
}
}
}
public void GetResult()
{
}
}
public class CustomAwaiter<T> : CustomAwaiter
{
private readonly T _result;
public CustomAwaiter(int simulateDelayMilliseconds, T result)
: base(simulateDelayMilliseconds)
{
_result = result;
}
public new T GetResult() => _result;
}
public class CustomException : Exception
{
public CustomException() : base("This is a custom exception.")
{
}
}
}
|