C#如何与第三方锁定摘要class

C# How to lock in abstract class with third parties

简介

我有一个 public 抽象 class,带有一个抽象方法,我想从工作线程调用它。

调用该方法时,应锁定相应的实例,以防止在计算过程中状态发生变化。

我只想使用抽象 class,因为继承者的实现是由第三方完成的。

public abstract class MyClass
{
    public abstract MyResult GetData();
}

问题

我的库被第三方使用,我不得不假设他们对库的内部实现一无所知。

我不想强迫他们研究我的 class 的文档,因为我认为这是一种糟糕的形式,他们才能实现自己的继承者。

我的做法

我的第一个想法是向 class 添加一个受保护的锁对象,并在调用该方法时锁定它。

但是,为了使它有用,第三方也必须锁定它,从而知道它。

因为我不想强迫第三方知道内部情况,所以我不喜欢这个选项。

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 模型的准备管道。

问题

如何在不知道其实现的情况下锁定整个对象?

如果没有这样的方法,那么对于这个问题是否有商定的模式或类似的东西?

My library is used by third parties, I have to assume that they know nothing about the internal implementation of the library. (..) When the method is called, the respective instance should be locked down in order to prevent state changes during calculation.

我认为最好的方法是.. 让他们知道,并确保他们知道他们对此负责。您可以轻松地使其直观而无需(很多)文档。

考虑将您的摘要 class 更改为类似以下内容:

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() { ....???.... }
}

现在,您有效地确保了:

  • 谁想要实现它,就必须提供他自己的类型,实现额外的接口
  • 实施那个额外接口的人 会注意到 这两个方法,他们 至少会想到 "wtf",并且会立即理解,或者将尝试查阅文档
  • 您没有锁定数据,class 的创建者对此负责
  • 实施者现在可以选择实际实施freeze/thaw对,或者将它们留空并简单地编写自己的代码以不同时修改数据
  • 您的代码现在必须适当地调用 'Freeze' 和 'Thaw',并且可以假设实现者做了他期望的事情

相反,如果你不能假设他做了他应该做的,那么改变你的库的 API 并且不允许用户定义的类型,并限制 API 只有你自己的类型,你可以确保它会很好玩。