Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程安全类库设计_C#_Oop - Fatal编程技术网

C# 线程安全类库设计

C# 线程安全类库设计,c#,oop,C#,Oop,我正在开发一个类库,并在设计中选择了一种使实现和线程安全稍微容易一些的方法,但是我想知道是否有更好的方法 一个简单的背景是,我在类库中有一个多线程启发式算法,一旦设置了一个场景,应该尝试解决它。不过,我显然希望它是线程安全的,如果有人在解决问题时对任何内容进行更改,就会导致崩溃或错误 当前的方法是,如果我有一个类a,那么我为每个实例创建一个InternalA实例。InternalA具有来自A类的许多重要属性,但在库之外是无法访问的内部属性 这样做的缺点是,如果我希望扩展决策逻辑(或者实际上让别人

我正在开发一个类库,并在设计中选择了一种使实现和线程安全稍微容易一些的方法,但是我想知道是否有更好的方法

一个简单的背景是,我在类库中有一个多线程启发式算法,一旦设置了一个场景,应该尝试解决它。不过,我显然希望它是线程安全的,如果有人在解决问题时对任何内容进行更改,就会导致崩溃或错误

当前的方法是,如果我有一个类a,那么我为每个实例创建一个InternalA实例。InternalA具有来自A类的许多重要属性,但在库之外是无法访问的内部属性

这样做的缺点是,如果我希望扩展决策逻辑(或者实际上让别人在库之外做),那么这意味着我需要更改InternalA中的代码(或者提供某种委托函数)


这听起来像是正确的方法吗?

仅从这一点很难说——但我可以说,如果你能让一切都不改变,你的生活就会轻松得多。看看函数式语言如何处理不可变的数据结构和集合。共享的可变数据越少,线程就越简单。

为什么不呢? 创建泛型类,该类接受2个成员类(例如,Lock/Unlock)——这样您就可以提供

  • Threadsafe impl(Implementation可以在内部使用Monitor.Enter/Exit)
  • 系统范围安全impl(使用互斥)
  • 不安全,但速度很快(使用空impl)

另一种我已经取得一些成功的方法是使用接口实现功能分离。这种方法的代价是,某些字段会“重复”,因为每个接口都需要与其他字段完全分离

在我的例子中,有两个线程需要传递一组数据,这些数据可能很大,需要尽可能少的垃圾收集。Ie我只想将更改信息从第一阶段传递到第二阶段。然后让第一个过程进入下一个工作单元

这是通过使用更改缓冲区将更改从一个接口传递到下一个接口来实现的

这允许一个线程在一个接口上工作,进行所有更改,然后发布一个包含其他接口(线程)在工作之前需要应用的更改的结构

通过这样做,您有一个双缓冲区。。。(线程1生成一个更改报告,而线程2使用最后一个报告)。如果添加更多的接口(和线程),则看起来好像有工作脉冲在线程中移动

这是基于我的研究,我毫不怀疑现在有更好的方法可用

然而,我提出这一点的目的是通过设计竞争条件来避免在绝大多数代码中使用锁。另一个主要考虑因素是垃圾收集的性能,这对您来说可能不是问题


在需要线程之间的复杂交互之前,这种方法都是好的。。。然后,您会发现您开始强制重新使用缓冲区结构的布局,以绕过继承,而继承又会带来维护开销。

有关此问题的更多信息将有助于

我使用的启发式方法是解决类似TSP的问题。在每一场比赛开始时会发生什么 计算结果是,形成问题的所有方面(销售人员/参观地点)都被克隆 因此,它们不会跨线程受到影响

这意味着每个线程都可以更改数据(例如销售人员留下的库存等),因为有一个数字 在计算过程中随着事情的进展而变化的值的集合。我很想做的是允许 对于使用该库的开发人员要重写的简单示例,请选中诸如hasufficientstock()之类的选项

然而,不幸的是,目前需要在线程之间添加进一步的保护,并使其更加简单/轻量级 类我将它们转换为这些内部类,这些是实际使用和克隆的东西

比如说

class A
{
   public double Stock { get; }

   // Processing and cloning actually works using these InternalA's
   internal InternalA ConvertToInternal() {}
}

internal class InternalA : ICloneable
{
   public double Stock { get; set; }

   public bool HasSufficientStock() {}
}

这会很酷。你知道有没有示例代码演示这类事情吗?很简单,每个实现不会超过10行代码。泛型类接受“Protector”-它可以从一些接口IProtector派生,方法为:Enter()Exit()为您的案例实现。在您的代码中,使用pair环绕敏感代码:尝试{MyProtector.Enter();…}最后{MyProtector.Exit();}或者使用IDisposable执行相同的操作,如果您使用此代码,请将我写给mvoronoy(*)yahoo(.)comDewfy,感谢您的回复。我可能会在某个时候给你发电子邮件,以获得更深入的示例,因为我不太确定我是否100%遵循了。不幸的是,我不认为我可以使事情一成不变。我在另一个答案中添加了更多信息。