0

0

c# 如何用 EventSource 和 EventListener 监控内部并发事件

煙雲

煙雲

发布时间:2026-01-15 09:58:47

|

168人浏览过

|

来源于php中文网

原创

EventSource 是 .NET 轻量级事件发布机制,只负责“写”;EventListener 是抽象基类,不可直接实例化,必须继承并重写 OnEventSourceCreated 和 OnEventWritten 才能接收事件。

c# 如何用 eventsource 和 eventlistener 监控内部并发事件

EventSource 是什么,为什么不能直接 new EventListener

EventSource 是 .NET 提供的轻量级、高性能事件发布机制,专为生产环境诊断设计;它本身不负责监听,只负责「写」。而 EventListener 是抽象基类,必须继承并重写 OnEventSourceCreatedOnEventWritten 才能接收事件——你不能直接 new EventListener(),否则毫无作用。

如何让自定义 EventListener 捕获并发相关事件(如 TaskScheduler、ThreadPool)

.NET 运行时自带多个内部 EventSource,比如 System.Threading.Tasks.TplEventSourceSystem.Runtime.ThreadPoolEventSource,它们默认是禁用的。要监听,必须在 OnEventSourceCreated 中显式启用对应事件源,并指定关键词(keyword)和等级(level)。

  • 关键词决定捕获哪类事件:例如 TaskScheduler 事件常用 EventSource.Settings.TaskScheduler(实际值为 0x10),ThreadPoolEventSource.Settings.ThreadPool(0x20)
  • 等级至少设为 EventLevel.Verbose 才能看到调度细节(如任务入队、线程唤醒)
  • 必须调用 EnableEvents(eventSource, level, keywords),且该调用需在 OnEventSourceCreated 内完成,延迟启用会丢事件
public class ConcurrencyEventListener : EventListener
{
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        if (eventSource.Name == "System.Threading.Tasks.TplEventSource")
        {
            EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)0x10); // TaskScheduler
        }
        else if (eventSource.Name == "System.Runtime.ThreadPoolEventSource")
        {
            EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)0x20); // ThreadPool
        }
    }

    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        if (eventData.EventName is "ScheduledTask" or "ThreadRequested" or "WorkerThreadStart")
        {
            Console.WriteLine($"[{eventData.EventSource.Name}] {eventData.EventName}: {string.Join(", ", eventData.PayloadNames.Zip(eventData.Payload, (n, v) => $"{n}={v}"))}");
        }
    }
}

常见漏掉的并发事件和调试陷阱

很多人以为启用了 TplEventSource 就能看见所有 Task 行为,但实际有三个关键限制:

  • TaskCreationOptions.RunContinuationsAsynchronouslyTask.Run 创建的任务才触发 ScheduledTask;同步 continuation(如 ContinueWith 默认行为)不会发事件
  • ThreadPoolEventSourceThreadRequested 只在“线程不足需扩容”时发出,空闲线程复用过程无事件
  • 若程序启动后才创建 ConcurrencyEventListener 实例,此前已发生的调度事件(尤其是 AppDomain 初始化阶段的)完全丢失——必须尽早 new 并保持存活
  • 事件负载高时(如每秒数千任务),OnEventWritten 是同步调用,阻塞会导致事件被丢弃;生产环境应异步缓冲或限流处理

验证是否真收到了并发事件的最简方法

不要依赖日志滚动——写个可复现的最小触发片段,配合断点或计数器确认:

Dora
Dora

创建令人惊叹的3D动画网站,无需编写一行代码。

下载
var listener = new ConcurrencyEventListener();
// 确保 listener 实例不被 GC(比如存为 static 字段)

Task.Run(() => Thread.Sleep(1)); // 触发 ThreadPool + Tpl 调度事件
Task.Factory.StartNew(() => { }, TaskCreationOptions.PreferFairness);

// 等待一小会儿再 Dispose,避免事件还在管道中
await Task.Delay(100);
listener.Dispose();

如果 OnEventWritten 完全没被调用,优先检查 EventSource.Name 是否拼错(大小写敏感)、.NET 版本是否支持(TplEventSource 在 .NET Core 2.1+ 稳定,.NET Framework 4.6.2+ 有但字段名不同)。

并发监控不是开箱即用的开关,每个 EventSource 都有自己隐含的触发边界和采样逻辑,想看到某类行为,得先确认它确实属于该事件源的输出范畴。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

61

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

31

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

71

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

20

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

7

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

4

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

49

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 46.1万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号