C# 如何与第三方锁定抽象类

标签 c# multithreading abstract

简介

我有一个公共(public)抽象类,带有一个抽象方法,我想从工作线程调用它。

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

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

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

问题

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

我不想强制他们在能够实现自己的继承者之前学习我的类的文档,因为我认为这种形式很糟糕。

我的方法

我的第一个想法是向类添加一个 protected 锁对象,并在调用方法时锁定它。

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

因为我不想强制第三方了解内部结构,所以我不喜欢这个选项。

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.

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

考虑将抽象类更改为:

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

现在,您有效地确保了:

  • 无论谁想要实现它,都必须提供自己的类型,实现额外的接口(interface)
  • 无论谁实现了这个额外的接口(interface)都会注意到这两个方法,他们至少会认为“wtf”,并且会立即理解,或者会尝试查阅文档
  • 您不对数据进行锁定,类的创建者对此负责
  • 实现者现在可以选择在何处实际实现卡住/解冻对,或者将其留空并简单地编写自己的代码,同时不修改数据
  • 您的代码现在必须适本地调用“卡住”和“解冻”,并且可以假设实现者做了他所期望的事情

相反,如果你不能假设他做了他所期望的那样,那么更改你的库的 API 并且不允许用户定义类型,并将 API 限制为仅你自己可以的类型确保效果很好。

关于C# 如何与第三方锁定抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42496247/

相关文章:

c - 我是否需要在编译时添加一个 _REENTRANT 宏以使我的 errno 线程安全?

Java接口(interface)和抽象中的返回类型

java - 类或接口(interface)实例之间的区别

具有抽象基类的 C++ 虚拟继承

c# - 适用于.NET的YouTube数据API客户端库-从 channel 列表中获取视频

C# 枚举与数据驱动列表

C# - 使用继承和运算符重载设计类

c# - 可以在 app.config 中模拟控制台应用程序吗?

ios - 等待要在下一次分派(dispatch)时执行的 block 如何成功?

ios - 异步下载多个文件与同步下载