Last active
February 18, 2016 14:34
-
-
Save negativeeddy/a0a363c6fe9e0316502d to your computer and use it in GitHub Desktop.
TPL exception behavior test. This demonstrates exception behavior based on whether the Task is ignored or awaited deep inside a callstack.
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.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace async_exception_test | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
MainAsync().Wait(); | |
Console.ReadLine(); | |
} | |
static async Task MainAsync() | |
{ | |
await RunTests(false); | |
await RunTests(true); | |
} | |
private static async Task RunTests(bool awaitFlag) | |
{ | |
doAwait = awaitFlag; | |
for (int i = 0; i < options.Length; i++) | |
{ | |
try | |
{ | |
funcID = i; | |
Console.WriteLine("{0} - {1}", | |
awaitFlag ? "AWAITING" : "FORGETTING", | |
options[funcID].Method.Name | |
); | |
await FooA(); | |
await Task.Delay(500); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex); | |
} | |
Console.WriteLine("------------------------------"); | |
} | |
} | |
private static async Task FooA() | |
{ | |
await Task.Delay(10); | |
await FooB(); | |
await Task.Delay(10); | |
} | |
private static async Task FooB() | |
{ | |
await Task.Delay(10); | |
await FooC(); | |
await Task.Delay(10); | |
} | |
static Func<Task>[] options = new Func<Task>[] | |
{ | |
ExceptionThrownNoTask, | |
ExceptionFromTask, | |
ExceptionBeforeAwaitAsync, | |
ExceptionAfterAwaitAsync, | |
}; | |
static int funcID; | |
static bool doAwait; | |
private static async Task FooC() | |
{ | |
Func<Task> theFunc = options[funcID]; | |
if (doAwait) | |
{ | |
await theFunc(); | |
} | |
else | |
{ | |
theFunc().Forget(); | |
} | |
} | |
static Task ExceptionThrownNoTask() | |
{ | |
throw new Exception("BROKEN"); | |
} | |
static Task ExceptionFromTask() | |
{ | |
return TaskHelper.FromException(new Exception("BROKEN")); | |
} | |
static async Task ExceptionBeforeAwaitAsync() | |
{ | |
throw new Exception("BROKEN"); | |
await Task.Delay(10); | |
} | |
static async Task ExceptionAfterAwaitAsync() | |
{ | |
await Task.Delay(10); | |
throw new Exception("BROKEN"); | |
} | |
} | |
public static class TaskHelper | |
{ | |
/// <summary> | |
/// This method does nothing with the Task. It is used to explicitly mark | |
/// Tasks as "Fire and Forget" to prevent warning CS1998 | |
/// </summary> | |
/// <param name="task">The task to ignore</param> | |
public static void Forget(this Task task) | |
{ | |
// do nothing | |
} | |
private static Task<bool> _completedTask; | |
public static Task CompletedTask | |
{ | |
get | |
{ | |
if (_completedTask == null) | |
{ | |
_completedTask = Task.FromResult(true); | |
} | |
return _completedTask; | |
} | |
} | |
/// <summary>Creates a Taskthat's completed exceptionally with the specified exception.</summary> | |
/// <param name="exception">The exception with which to complete the task.</param> | |
/// <returns>The faulted task.</returns> | |
public static Task FromException(Exception exception) | |
{ | |
return FromException<bool>(exception); | |
} | |
/// <summary>Creates a Task that's completed exceptionally with the specified exception.</summary> | |
/// <typeparam name="TResult">The type of the result returned by the task.</typeparam> | |
/// <param name="exception">The exception with which to complete the task.</param> | |
/// <returns>The faulted task.</returns> | |
public static Task<TResult> FromException<TResult>(Exception exception) | |
{ | |
if (exception == null) throw new ArgumentNullException("exception"); | |
TaskCompletionSource<TResult> tsc = new TaskCompletionSource<TResult>(); | |
tsc.SetException(exception); | |
return tsc.Task; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment