Skip to content

Instantly share code, notes, and snippets.

@Porges
Last active October 7, 2015 21:31
Show Gist options
  • Save Porges/169f1f205075a4ae1768 to your computer and use it in GitHub Desktop.
Save Porges/169f1f205075a4ae1768 to your computer and use it in GitHub Desktop.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncCLI
{
public sealed class Program
{
// Main handles command line parsing and invocation
// of strongly-typed main method.
public static int Main(string[] args)
{
try
{
var options = new Options(/*args*/);
// parse options somehow - use a library!
// or return (int)ExitCode.InvalidArguments
return (int)RunProgram(options);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
return (int)ExitCode.UnexpectedError;
}
}
public sealed class Options
{
}
// Possible exit codes of the program:
public enum ExitCode
{
Success = 0,
Cancelled = 1,
InvalidArguments = 2,
UnexpectedError = -1,
}
// Strongly-typed main method. Testing is easier via this entrypoint.
public static ExitCode RunProgram(Options options)
{
using (var cts = new CancellationTokenSource())
{
ConsoleCancelEventHandler consoleCancellationHandler =
(sender, eventArgs) =>
{
eventArgs.Cancel = true;
cts.Cancel();
Console.Error.WriteLine("Requesting cancellation...");
};
Console.CancelKeyPress += consoleCancellationHandler;
try
{
// set up, e.g. loggers and other low-level dependencies:
var dependency1 = new object();
var dependency2 = new object();
new Program(dependency1, dependency2)
.Run(cts.Token)
.Wait(cts.Token); // must be passed to Wait to throw OperationCanceledException
return ExitCode.Success;
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions)
{
Console.Error.WriteLine(inner);
}
return ExitCode.UnexpectedError;
}
catch (OperationCanceledException)
{
Console.Error.WriteLine("Cancelled.");
return ExitCode.Cancelled;
}
finally
{
Console.CancelKeyPress -= consoleCancellationHandler;
}
}
}
public Program(object injected, object dependencies)
{
}
public async Task Run(CancellationToken ct)
{
Console.WriteLine("Sleeping...");
await Task.Delay(TimeSpan.FromSeconds(5), ct);
Console.WriteLine("Woke up!");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment