【发布时间】:2019-12-10 13:00:47
【问题描述】:
我正在编写一个 C# 类来装饰可以引发事件的对象。装饰器可以实例化一个新的装饰对象并交换旧的对象,以响应任何消费线程上发生的异步事件。在初始化新装饰对象时,我需要将旧装饰对象中的所有事件处理程序添加到新装饰对象中,并继续从两个对象中添加/删除处理程序,直到发生交换。这个问题有现成的通用解决方案吗?
这是正在发生的事情的概念示例:
interface IFoo
{
event Action Barred;
void Bar();
}
class BasicFoo : IFoo
{
public event Action Barred;
public void Bar()
{
Console.WriteLine("Barring");
Barred?.Invoke();
}
}
class DecoratedFoo : IFoo
{
private IFoo _Decorated;
public DecoratedFoo()
{
_Decorated = new BasicFoo();
}
public event Action Barred
{
add => _Decorated.Barred += value;
remove => _Decorated.Barred -= value;
}
public void Bar() => _Decorated.Bar();
public void SwapDecoratedFoo()
{
// Can occur at any time from any thread.
var newFoo = new BasicFoo();
/*
* How to reassign events from _Decorated to newFoo, and in a way
* that's thread safe while _Decorated.Barred may still be adding
* or removing handlers while the swap is occurring?
*/
Interlocked.Exchange(ref _Decorated, newFoo);
}
}
【问题讨论】:
-
可以在类代码中进行分配。虽然外部代码只能添加和删除事件处理程序 - 通过(隐藏的)添加/删除函数/类似属性的构造 - 类代码可以完全访问支持变量,包括赋值。
标签: c# events thread-safety decorator