/// <summary> /// Processes the specified log messages asynchronously /// (the method is executed by the stage's processing thread, do not use <c>ConfigureAwait(false)</c> to resume /// execution in the processing thread when awaiting a task). /// </summary> /// <param name="messages">Messages to process.</param> /// <param name="cancellationToken">Cancellation token that is signaled when the pipeline stage is shutting down.</param> /// <remarks> /// Call <see cref="LocalLogMessage.AddRef"/> on a message that should be stored any longer to prevent it from /// returning to the log message pool too early. Call <see cref="LocalLogMessage.Release"/> as soon as you don't /// need the message any more. /// </remarks> protected override async Task ProcessAsync(LocalLogMessage[] messages, CancellationToken cancellationToken) { // enqueue messages to process // (helps to defer messages that could not be processed successfully) foreach (var message in messages) { message.AddRef(); var formattedMessage = new FormattedMessage { Message = message, // ReSharper disable once InconsistentlySynchronizedField Output = mFormatter.Format(message) }; mFormattedMessageQueue.Enqueue(formattedMessage); } if (mFormattedMessageQueue.Count > 0) { int count = await EmitOutputAsync(mFormattedMessageQueue.ToArray(), cancellationToken); for (int i = 0; i < count; i++) { var item = mFormattedMessageQueue.Dequeue(); item.Message.Release(); } } }
/// <summary> /// TBD /// </summary> /// <returns>TBD</returns> public override string ToString() { return(_formatter.Format(Format, Args)); }