此设计的螺纹安全性

本文关键字:安全性 | 更新日期: 2023-09-27 18:21:20

我继承了一些C#代码来维护,我对设计有一些保留,但我不知道是否应该这样做。这是用于控制某些工业过程的C#应用程序。

我们有一个方法DoCertify(),它启动一个工作线程来控制一系列工业过程。在序列的每个步骤中,它控制一些机器,然后编译一些数据。

调用方在UI线程中分配一个表示这些步骤的对象数组,并调用DoCertify(),将数组作为ref变量传递。序列中的每个步骤完成后,DoCertify()的工作线程会定期填充数组的相关元素(步骤0、元素0、步骤1、元素1等)中的数据,并调用一个委托(即对UI线程的回调)来宣布该步骤完成,然后继续下一步。

当调用UI线程中的回调时,它读取并显示刚刚完成的数组元素中的数据。通过这种方式,当DoCertify()运行时,其进度可以在显示器上更新。

这里面没有明确的线程安全性,但代码的编写者说,它本质上是安全的,因为一旦工作线程写入一个元素并发出完成的信号,它就再也不会写入该元素,所以工作线程和UI线程尝试同时访问数组中的同一元素是没有危险的。

这是否提供了足够的螺纹安全性,还是应该在设计中加入更明确的螺纹安全?

此设计的螺纹安全性

它是线程安全的,但不安全。我的意思是如果你说的是真的,调用者在被调用者调用回调之前不会读取任何内容,并且调用者在切换到工作者之后没有修改原始数据,等等——你就没事了。

但这并不安全,因为开发人员将来可能很容易做一些事情,比如尝试在调用之间重用数组、向数组添加值、更改值,或者利用ref认为他们可以在同一范围内使用这些值。谁知道呢。

您描述的设计无法防止任何一端的不当行为。在数组副本(以及数组元素副本)上工作的设计是更好的选择。