从 Component 到 BackgroundWorker

在 .NET Framework 2.0 时代,微软引入了 BackgroundWorker 来解决 WinForm/WPF 场景下“耗时操作阻塞 UI 线程”的问题;而 Component 早在 1.0 就已存在,是所有可视化/非可视化设计器的“基类”。理解这两者的源码与机制,可以帮助我们:

更精确地调试遗留代码;

在需要设计时支持时(如自定义控件/组件)少走弯路;

在无法使用 async-await 的老项目中做最小侵入式改造。

2️⃣ Component 类:所有“组件”的鼻祖
2.1 命名空间与程序集

// 所在程序集:System.ComponentModel.Primitives.dll
namespace System.ComponentModel

2.2 继承链与接口实现

System.Object
└─ System.MarshalByRefObject // 支持跨 AppDomain 远程调用
└─ System.ComponentModel.Component
├─ 实现 IComponent // 提供 Site 与 Disposed 事件
└─ 实现 IDisposable // 标准 Dispose 模式

2.3 设计时元数据
[ComVisible(true)]:可被 COM 调用。

[ClassInterface(ClassInterfaceType.AutoDispatch)]:为 COM 客户端生成双重接口。

[DesignerCategory(“Component”)]:告诉 Visual Studio 使用 ComponentDesigner。

2.4 核心字段与线程安全

private static readonly object EventDisposed = new object();
private ISite site;
private EventHandlerList events; // 延迟创建,减少内存

  • 所有事件都通过 EventHandlerList 存储,避免每个事件一个字段,节省内存。
  • 对 events 的访问采用“延迟初始化 + 双检锁”。

2.5 事件系统:EventHandlerList 的魔法

public event EventHandler Disposed
{
add { Events.AddHandler(EventDisposed, value); }
remove { Events.RemoveHandler(EventDisposed, value); }
}

  • 通过 object 类型的 key(而非字符串)避免冲突。
  • EventHandlerList 内部使用单向链表,添加/删除 O(1)。

2.6 Dispose 模式深度解析

~Component() { Dispose(false); }

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!disposing) return;

lock (this)
{
if (site?.Container != null)
site.Container.Remove(this); // 设计器撤销时自动清理

((EventHandler)events?[EventDisposed])?.Invoke(this, EventArgs.Empty);
}
}

标准 Dispose 模式 + lock(this) 保证线程安全。

在 VS 设计器中,当用户从设计面板上删除组件时,Container.Remove 会触发 Dispose。

2.7 设计时支持:Site / Container / DesignMode
ISite:为组件提供“宿主”信息(名称、容器、设计模式标志、全局服务)。

IContainer:管理一组组件的生命周期。

DesignMode:运行时永远返回 false,仅在设计器进程返回 true。

欢迎使用66资源网
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
7. 本站有不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!

66源码网 » 从 Component 到 BackgroundWorker

提供最优质的资源集合

立即查看 了解详情