Skip to content

Instantly share code, notes, and snippets.

@thenameless314159
Created June 27, 2017 10:15
Show Gist options
  • Save thenameless314159/e3f28cfd3cabd9257de312cfa916933f to your computer and use it in GitHub Desktop.
Save thenameless314159/e3f28cfd3cabd9257de312cfa916933f to your computer and use it in GitHub Desktop.
High performance async/sync logger factory using TPL
public class LoggerFactory
{
public ILogger Logger { get; }
public AsyncCollection<LogMessage> MessageCollection { get; }
private ILogWriter LogWriter { get; }
private CancellationTokenSource MainTokenSource { get; }
private TaskFactory DispatcherFactory()
=> new TaskFactory(
MainTokenSource.Token,
TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
private LoggerFactory(CancellationTokenSource mainCancellationTokenSource, TextBlock logger)
{
MessageCollection = new AsyncCollection<LogMessage>();
MainTokenSource = mainCancellationTokenSource ?? new CancellationTokenSource();
Logger = new AsyncLogger(MessageCollection, MainTokenSource);
LogWriter = new AsyncLogWriter(logger);
}
private LoggerFactory() : this(null, null) { }
public static LoggerFactory CreateDefault()
=> new LoggerFactory();
public static LoggerFactory Create(TextBlock textBlock)
=> new LoggerFactory(null, textBlock);
public static LoggerFactory Create(CancellationTokenSource mainToken, TextBlock textBlock)
=> new LoggerFactory(mainToken, textBlock);
/// <summary>
/// Launch <see cref="DispatcherFactory"/>
/// </summary>
/// <returns>A cyclic <see cref="TaskFactory"/></returns>
/// <remarks>This <see cref="TaskFactory"/> is attached to Main method of the App entry point,
/// therefore if app is cancelled, this factory will also cancel</remarks>
public async Task LaunchFactory()
=> await DispatcherFactory().StartNew( async () =>
{
try
{
for (;;)
{
var takeResult = await MessageCollection.TryTakeAsync(MainTokenSource.Token);
if (!takeResult.Success)
continue;
await LogWriter.WriteMessageAsync(takeResult.Item).ConfigureAwait(false);
}
}
catch (Exception e)
{
await Logger.AddErrorAsync(string.Empty, e);
throw;
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment