让孩子。net中使用DiagnosticSource

  介绍

让孩子。net中使用DiagnosticSource ?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

DiagnosticSource是一个非常有意思的且非常有用的API,对于这些API它们允许不同的库发送命名事件,并且它们也允许应用程序订阅这些事件并处理它们,它使我们的消费者可以在运行时动态发现数据源并且订阅与其相关的数据源。

DiagnosticSource在AspNetCore, EntityFrameworkCore, HttpClient, SqlClient中被使用,在我们实际的开发过程中他使我们能够进行拦截请求与响应的http请求,数据库查询,对HttpContext, DbConnection, DbCommand, HttpRequestMessageand等对象的访问,甚至说在需要的时候我们可以进行修改这些对象来处理我们的业务。

下面我们将通过如下的简单示例来了解它。


DiagnosticSource和EventSource在架构设计上很相似,他们的主要区别是EventSource它记录的数据是可序列化的数据,会被进程外消费,所以要求记录的对象必须是可以被序列化的。而DiagnosticSource被设计为在进程内处理数据,所以我们通过它拿到的数据信息会比较丰富一些,它支持非序列化的对象,比如HttpContext, HttpResponseMessage等。另外如果想在EventSource中获取DiagnosticSource中的事件数据,可以通过DiagnosticSourceEventSource这个对象来进行数据桥接。


为了更好的理解DiagnosticSource的工作方式,如下这个示例将拦截数据库请求,假设我们有一个简单的控制台应用程序,它向数据库发出请求并将结果输出到控制台。

类项目
  {
  ConnectionString=公共常量字符串
  @"服务器=localhost;数据库=主;Trusted_Connection=True;“;
  静态异步任务Main (string [] args)
  {
  var=等待得到结果();
  Console.WriteLine(结果);
  
  }
  公共静态异步TaskGet () {
  使用(var连接=new SqlConnection (ConnectionString))
  {
  返回等待connection.QuerySingleAsync(“选择42“);
  }
  }
  }

我们再来思考一下,假设来了一个需求:我们需要获取到所有数据库查询的执行时间,或者说我们要进行获取执行的一些sql语句或者数据进行存储作为记录我们该如何处理?
好了下面我们将尝试使用DiagnosticSource来实现该需求。


来吧,我们先来创建一个类作为该事件的处理程序或者说作为该事件的消费者。

静态异步任务Main (string [] args)
  {
  var观察者=new ExampleDiagnosticObserver ();
  IDisposable订阅=DiagnosticListener.AllListeners.Subscribe(观察者);
  var=等待得到结果();
  Console.WriteLine(结果);
  }

下面我们再来修改我们的ExampleDiagnosticObserver类,其实如上代码片段中编译器已经提醒我们要实现接口IObserver

(对象的值,字符串名称)
  {
  返回(T) value.GetType ()
  . getproperty(名字)
  .GetValue(价值);
  }

在这我们将拦截数据库中查询的开始和结束事件,在执行之前我们创建并且启动秒表,将其存储在AsyncLocal中,以后面将其返回,在执行完成后,我们获取之前启动的秒表,停止它,通过反射从参数值中获取执行命令,并将结果输出到控制台。

让孩子。net中使用DiagnosticSource