上面虽然我们实现了需求,但是我们也可以发现我们从DiagnosticListener接收到的事件参数通常作为匿名对象传递,因此通过反射去处理这些参数这样给我们造成了比较昂贵的消耗,不过开发团队也考虑到了该问题向我们提供了Microsoft.Extensions.DiagnosticAdapter来完成我们的操作。
下面我们需要将Subscribe改为SubscribeWithAdapter,另外在这种情况下我们不需要实现IObserver<KeyValuePair<string, object>>接口,相反的是我们需要为每个事件声明一个单独的方法,并且使用[DiagnosticNameAttribute]特性去标注
如下所示:
public class ExampleDiagnosticObserver4 : IObserver<DiagnosticListener> { private readonly List<IDisposable> _subscriptions = new List<IDisposable>(); private readonly AsyncLocal<Stopwatch> _stopwatch = new AsyncLocal<Stopwatch>(); public void OnCompleted() { } public void OnError(Exception error) { } public void OnNext(DiagnosticListener value) { if (value.Name == "SqlClientDiagnosticListener") { var subscription = value.SubscribeWithAdapter(this); _subscriptions.Add(subscription); } } [DiagnosticName("System.Data.SqlClient.WriteCommandBefore")] public void OnCommandBefore() { _stopwatch.Value = Stopwatch.StartNew(); } [DiagnosticName("System.Data.SqlClient.WriteCommandAfter")] public void OnCommandAfter(DbCommand command) { var stopwatch = _stopwatch.Value; stopwatch.Stop(); Console.WriteLine($"CommandText: {command.CommandText}"); Console.WriteLine($"Elapsed: {stopwatch.Elapsed}"); Console.WriteLine(); } }
现在我们实现了对数据执行的监控或者说拦截功能,同时也能为我们的数据库执行时间做记录,并且特别注意的是我们并没有对应用程序本身做修改,这样也减轻了很多的冗余,同时节省了大量的编码时间。这是一个很不错的编程体验。
创建DiagnosticListener实例
在大多数情况下,我们对DiagnosticSource都会去订阅已经存在的事件,基本我们都不需要去创建自己的DiagnosticListener去发送事件,当然去了解一下这一特性也是比较好的,请继续往下看
创建自己的实例
private static readonly DiagnosticSource diagnosticSource = new DiagnosticListener("MyLibraty");
发送事件,我们将调用Write进行写入事件
if (diagnosticSource.IsEnabled("MyEvent")) diagnosticSource.Write("MyEvent", new { /* parameters */ });
参考
https://sudonull.com/post/3671-Using-the-DiagnosticSource-in-NET-Core-Theory
https://github.com/dotnet/runtime/issues/20992
https://github.com/hueifeng/BlogSample/tree/master/src/DiagnosticDemo
到此这篇关于在.NET中使用DiagnosticSource的方法的文章就介绍到这了,更多相关.NET使用DiagnosticSource内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章: