我正在C#中编写一个低级键盘钩子,我最重要的是避免随机的,非确定性的延迟,例如来自GC。我的第二个优先事项是让它尽可能快地运行 - 这是一个“很好的”,而不是“必须拥有”。
我的程序为键盘事件的每个“订阅者”都有一个帖子。一个订户线程可以订阅多个键盘事件。只有订阅者才能修改自己的订阅,即不允许一个帖子订阅或取消订阅另一个帖子。
我的键盘钩子的逻辑是:
我目前对第2步的想法是从ConcurrentDictionary获取订阅者信息。这是HotkeySubscriberInfo的简化版本:
class HotkeySubscriberInfo
{
private ISet<Subscriber> _subscribers;
private Subscriber[] _memoizedSubscriberEnumeration;
private object _writeMutex;
private object _readMutex;
}
HotkeySubscriberInfo会像这样突变:
lock (_writeMutex)
{
// add or remove a subscriber
Subscriber[] memoized = subscribers.ToArray();
lock (_readMutex)
{
_memoizedSubscriberEnumeration = memoized;
}
}
键盘钩子只会锁定_readMutex
,将数组放入局部变量并对其进行for循环。
我的问题是:我可以摆脱_readMutex
并在键盘钩子中使用Volatile.Read
吗?我知道这意味着键盘钩并不总是“立即”获得“新鲜”值,但只要该值不太陈旧(例如订阅者未订阅,在按下某人之前一整秒通过),这是可接受的行为热键和订阅者无论如何都会获取热键,因为订阅者列表是陈旧的。)