简介
我有一个公共抽象类,带有一个抽象方法,我想从工作线程调用它。
调用该方法时,应锁定相应的实例,以防止在计算过程中状态发生变化。
我只想使用抽象类,因为继承者的实现是由第三方完成的。
public abstract class MyClass
{
public abstract MyResult GetData();
}
问题
我的图书馆被第三方使用,我必须假设他们对图书馆的内部实施一无所知。
我不想强迫他们研究我班级的文档,然后才能实现他们自己的继承人,因为我认为这是一种不好的形式。
我的方法
我的第一个想法是在类中添加一个受保护的锁对象,并在调用该方法时锁定它。
但是,为了使其有用,第三方也必须锁定它,从而了解它。
由于我不想迫使第三方了解内幕,我不喜欢这个选项。
public abstract class MyClass
{
protected readonly object myLock = new object();
public MyResult GetData()
{
MyResult result;
lock(myLock)
{
result = GetDataInternal();
}
return result;
}
protected abstract MyResult GetDataInternal();
}
背景
我正在处理一个在单独线程上运行的数据管道。
此管道以特定格式请求数据并在后台处理它。
提供数据可能需要一些时间,并且提供的数据依赖于对象的属性。
在这种情况下,它是3D模型的准备管道。
问题
如何在不知道其实现的情况下锁定整个对象?
如果没有这种方式,那么是否有一个商定的模式或类似的问题?
答案 0 :(得分:2)
我的图书馆被第三方使用,我必须假设他们对图书馆的内部实施一无所知。 (..) 调用该方法时,应锁定相应的实例,以防止在计算过程中状态发生变化。
我认为最好的方法是......让他们知道,并确保他们知道他们对此负责。如果没有(很多)文档,您可以轻松实现直观。
考虑将您的抽象类更改为:
public interface ILockable
{
void FreezeDataForCalculations();
void ThawAfterCalculations();
}
public abstract class MyBaseClass<T> where T:ILockable
{
public abstract T GetData();
}
用法:
public class MyThingie : MyBaseClass<TheActualData>
{
}
public class TheActualData : ILockable
{
public string Foo {get;set;}
public void FreezeDataForCalculations() { ...???...}
public void ThawAfterCalculations() { ....???.... }
}
现在,您有效地确保了:
相反,如果你不能认为他做了他应该做的事,那就更改你的库的API并且不允许用户定义的类型,并且只限制你自己的API你可以确保它们发挥得很好的类型。