IObserver 与 DiagnosticSource
观察者模式 IObserver
观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式。
适用于基于推送通知的方案。其类图如下:
在 .NET 中,通过实现泛型 System.IObservable<T> 和 System.IObserver<T> 接口来应用观察者设计模式。具体的代码实现见MSDN。
DiagnosticSource
DiagnosticSource 是观察者模式的一个实现,类库提过了一组API发出程序运行时的日志诊断记录,程序可以订阅这些日志记录。这些日志可以包含丰富的额外信息,帮助诊断程序内部发生的事情。
.net 类库 如 AspNetCore, EntityFrameworkCore, HttpClient, and SqlClient, 等第三方库cap,MassTransit,Elasticsearch 的.NET客户端都有DiagnosticSource 实现。
DiagnosticSource是一个抽象类,所以真正使用的是DiagnosticListener类。
如何定义自己的DiagnosticSource
1.创建DiagnosticListener。
2.编写DiagnosticListener 事件的扩展方法。
public static class LockNessDiagNosticListenerExtension { public const string DiagnosticListenerName = "NessClientDiagnosticListener"; private const string NessClientPrefix = "Custmer.Ness."; public const string NessBeforeExecuteCommand = NessClientPrefix + nameof(WriteBefore); public const string NessAfterExecuteCommand = NessClientPrefix + nameof(WriteAfter); public static Guid WriteBefore(this DiagnosticListener @this, [CallerMemberName] string operation = "") { if (@this.IsEnabled(NessBeforeExecuteCommand)) { Guid operationId = Guid.NewGuid(); @this.Write( NessBeforeExecuteCommand, new { OperationId = operationId, Operation = operation, Command = "WriteCommandBefore" }); return operationId; } else return Guid.Empty; } public static void WriteAfter(this DiagnosticListener @this, Guid operationId,long bgtime, [CallerMemberName] string operation = "") { if (@this.IsEnabled(NessAfterExecuteCommand)) { @this.Write( NessAfterExecuteCommand, new { OperationId = operationId, Operation = operation, Command = "WriteCommandAfter", Timestamp = Stopwatch.GetTimestamp(), excuttime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - bgtime }) ;; } } } public class NessExcutes { private static readonly DiagnosticListener _diagnosticListener = new DiagnosticListener(LockNessDiagNosticListenerExtension.DiagnosticListenerName); public async Task Excue() { var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var gid= _diagnosticListener.WriteBefore(); await Task.Delay(5000); _diagnosticListener.WriteAfter(gid, now); } }
3.实现事件的订阅
public class NessDiagnosticObserver : IObserver<DiagnosticListener>, IObserver<KeyValuePair<string, object>> { private readonly List<IDisposable> _subscriptions = new List<IDisposable>(); public void OnCompleted() { } public void OnError(Exception error) { } public void OnNext(KeyValuePair<string, object> value) { Console.WriteLine($"data is initializing {value} "); Write(value.Key, value.Value); } public void OnNext(DiagnosticListener value) { if (value.Name == "NessClientDiagnosticListener") { var subscription = value.Subscribe(this); _subscriptions.Add(subscription); } } private readonly AsyncLocal<Stopwatch> _stopwatch = new AsyncLocal<Stopwatch>(); private void Write(string name, object value) { switch (name) { case "Custmer.Ness.WriteBefore": { _stopwatch.Value = Stopwatch.StartNew(); break; } case "Custmer.Ness.WriteAfter": { var stopwatch = _stopwatch.Value; stopwatch.Stop(); Console.WriteLine($"Elapsed: {stopwatch.Elapsed}"); Console.WriteLine(); break; } } } }
public static async Task Main() { var observer = new NessDiagnosticObserver(); IDisposable subscription = DiagnosticListener.AllListeners.Subscribe(observer); OwnLibDiagNostic.NessExcutes nessExcutes = new OwnLibDiagNostic.NessExcutes(); await nessExcutes.Excue(); }
作者:RunStone
出处:https://www.cnblogs.com/RunStone/p/15813702.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
net core
, DiagnosticSource
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2021-01-18 规约Specification模式