11using System ;
2- using System . Collections . Concurrent ;
32using 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+
510namespace 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)
7883internal 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}
0 commit comments