WeakTypes - Axvser/MinimalisticWPF GitHub Wiki
类名 | 描述 | 使用场景 |
---|---|---|
WeakCache<TTargetKey, TCacheKey> |
弱引用字典式缓存 | 若存在对象集合,且需要周期性地遍历集合,使用与对象相关联的上下文缓存执行后续操作,那么可以使用这个类以在不阻止GC的前提下,维护对象与缓存的联系 |
WeakDelegate<TDelegate> |
弱引用事件处理器集合 | 用于不希望阻止订阅者被GC回收的事件处理器 |
WeakQueue<T> |
弱引用先进先出集合 | 需要弱引用队列语义时 |
WeakStack<T> |
弱引用后进先出集合 | 需要弱引用堆栈语义时 |
注意,若您永远不调用 ForeachCache 操作,也不调用 TryGetCache 操作,那么即便对象与对应的缓存能被回收,其弱引用仍会占据一定空间,这是不好的实践
// 管理所有活跃的WebSocket连接
var wsCache = new WeakCache<WebSocketClient, SessionState>();
// 新连接建立时
wsCache.AddOrUpdate(client, new SessionState {
UserId = userId,
ConnectTime = DateTime.Now
});
// 定时任务:向所有连接发送心跳
wsCache.ForeachCache((client, state) =>
{
if (DateTime.Now - state.LastHeartbeatTime > HeartbeatInterval)
{
client.Send(new HeartbeatMessage());
state.LastHeartbeatTime = DateTime.Now;
}
});
注意,不要滥用这个类,如果您使用诸如 KeyEventHandler 这样的事件,那它自身就是弱事件模型,与 WeakDelegate 结合使用将导致意外的GC回收
// 创建弱事件处理器集合
var weakHandlers = new WeakDelegate<EventHandler<EventArgs>>();
// 添加处理器
weakHandlers.AddHandler(MyEventHandler);
// 调用所有存活的处理器
var invocationList = weakHandlers.GetInvocationList();
invocationList?.Invoke(this, EventArgs.Empty);
// 移除处理器
weakHandlers.RemoveHandler(MyEventHandler);
与正常的队列用起来差不多,只是对于其中已经被GC回收的部分,会直接略过,例如 A → B → C,我本应取出 A → B → C,可由于B已被GC回收,我两次取出即可拿到 A → C 而无需取三次
// 创建弱引用队列
var queue = new WeakQueue<MyResource>();
// 添加项目
queue.Enqueue(new MyResource());
queue.EnqueueRange(resourceList);
// 处理项目
while (queue.TryDequeue(out var resource))
{
resource.DoSomething();
}
// 检查内容
if (queue.TryPeek(out var nextItem))
{
// 预览下一个项目
}
与正常的栈用起来差不多,只是对于其中已经被GC回收的部分,会直接略过,例如 A → B → C ,我原本应取出 C → B → A ,可由于B已被GC回收,我两次出栈操作即可返回 C → A 而无需三次出栈
// 创建弱引用堆栈
var stack = new WeakStack<MyResource>();
// 压入项目
stack.Push(new MyResource());
stack.PushRange(resourceList);
// 处理项目
while (stack.TryPop(out var resource))
{
resource.DoSomething();
}
// 检查顶部项目
if (stack.TryPeek(out var topItem))
{
// 查看顶部项目
}