Skip to content

Commit 9e1814d

Browse files
authored
Merge pull request #33 from dotnet-campus/t/walterlv/channel
优化日志写入性能,公开后台写入日志相关的方法
2 parents 0c12fae + 1b203fe commit 9e1814d

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

src/dotnetCampus.Logger/Writers/Helpers/ICoreLogWriter.cs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
using System;
2-
using System.Collections.Concurrent;
32
using System.Threading.Tasks;
43

4+
#if NET6_0_OR_GREATER
5+
using System.Threading.Channels;
6+
#else
7+
using System.Collections.Concurrent;
8+
#endif
9+
510
namespace dotnetCampus.Logging.Writers.Helpers;
611

712
/// <summary>
813
/// 提供各种不同线程安全方式的最终日志写入功能。
914
/// </summary>
10-
internal interface ICoreLogWriter
15+
public interface ICoreLogWriter
1116
{
1217
/// <summary>
1318
/// 写入日志。
@@ -78,32 +83,89 @@ public void Do(Action action)
7883
internal sealed class ProducerConsumerLogWriter : ICoreLogWriter
7984
{
8085
private readonly Action<string> _logger;
86+
#if NET6_0_OR_GREATER
87+
private readonly Channel<object> _queue = Channel.CreateUnbounded<object>(new UnboundedChannelOptions
88+
{
89+
SingleReader = true,
90+
SingleWriter = false,
91+
AllowSynchronousContinuations = false,
92+
});
93+
#else
8194
private readonly BlockingCollection<object> _queue = new();
95+
#endif
8296

8397
/// <summary>
8498
/// 创建 <see cref="ProducerConsumerLogWriter"/> 的新实例,并启动消费线程。
8599
/// </summary>
86100
public ProducerConsumerLogWriter(Action<string> logger)
87101
{
88102
_logger = logger;
103+
#if NET6_0_OR_GREATER
104+
_ = Task.Run(Consume);
105+
#else
89106
new Task(Consume, TaskCreationOptions.LongRunning).Start();
107+
#endif
90108
}
91109

92110
/// <inheritdoc />
93111
public void Write(string? message)
94112
{
95113
if (message is not null)
96114
{
115+
#if NET6_0_OR_GREATER
116+
_queue.Writer.TryWrite(message);
117+
#else
97118
_queue.Add(message);
119+
#endif
98120
}
99121
}
100122

101123
/// <inheritdoc />
102124
public void Do(Action action)
103125
{
126+
#if NET6_0_OR_GREATER
127+
_queue.Writer.TryWrite(action);
128+
#else
104129
_queue.Add(action);
130+
#endif
105131
}
106132

133+
#if NET6_0_OR_GREATER
134+
/// <summary>
135+
/// 消费队列中的元素。
136+
/// </summary>
137+
private async Task Consume()
138+
{
139+
while (true)
140+
{
141+
var success = await _queue.Reader.WaitToReadAsync();
142+
if (!success)
143+
{
144+
break;
145+
}
146+
147+
while (_queue.Reader.TryRead(out var item))
148+
{
149+
try
150+
{
151+
switch (item)
152+
{
153+
case string message:
154+
_logger(message);
155+
break;
156+
case Action action:
157+
action();
158+
break;
159+
}
160+
}
161+
catch (Exception)
162+
{
163+
// 本次日志发生了异常,已经无法继续写入日志,只能抛弃异常。
164+
}
165+
}
166+
}
167+
}
168+
#else
107169
/// <summary>
108170
/// 消费队列中的元素。
109171
/// </summary>
@@ -122,4 +184,5 @@ private void Consume()
122184
}
123185
}
124186
}
187+
#endif
125188
}

src/dotnetCampus.Logger/Writers/LogWritingThreadMode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public enum LogWritingThreadMode
3030
/// <summary>
3131
/// 包含 <see cref="LogWritingThreadMode"/> 的扩展方法。
3232
/// </summary>
33-
internal static class LogWritingThreadModeExtensions
33+
public static class LogWritingThreadModeExtensions
3434
{
3535
/// <summary>
3636
/// 根据 <see cref="LogWritingThreadMode"/> 创建对应的 <see cref="ICoreLogWriter"/> 实例。

0 commit comments

Comments
 (0)