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

时间:2017-02-27 21:38:53

标签: c# multithreading abstract

简介

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

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

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

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

问题

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

如果没有这种方式,那么是否有一个商定的模式或类似的问题?

1 个答案:

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

现在,您有效地确保了:

  • 无论谁想要实现它,都必须提供自己的类型,实现额外的接口
  • 实现额外界面的人会注意到这两种方法,而 至少会认为&#34; wtf&#34;,并且会立即理解,或者将尝试查阅文档
  • 你没有锁定数据,类的创建者负责它
  • 实现者现在可以选择来实际实现冻结/解冻对,或者将它们留空并简单地编写自己的代码以便在此期间不修改数据
  • 您的代码现在必须致电&#39; Freeze&#39;和&#39;解冻&#39;适当地,并且可以假设实现者做了他期望的

相反,如果你不能认为他做了他应该做的事,那就更改你的库的API并且不允许用户定义的类型,并且只限制你自己的API你可以确保它们发挥得很好的类型。