Created
June 27, 2017 10:15
-
-
Save thenameless314159/e3f28cfd3cabd9257de312cfa916933f to your computer and use it in GitHub Desktop.
High performance async/sync logger factory using TPL
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
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