Sou*_*rgy 5 c# struct thread-safety
我们知道,在C#中,结构是按值传递的,而不是通过引用传递的.所以,如果我有一个包含以下数据成员的结构:
private struct MessageBox
{
// data members
private DateTime dm_DateTimeStamp; // a struct type
private TimeSpan dm_TimeSpanInterval; // also a struct
private ulong dm_MessageID; // System.Int64 type, struct
private String dm_strMessage; // an object (hence a reference is stored here)
// more methods, properties, etc ...
}
Run Code Online (Sandbox Code Playgroud)
因此,当MessageBox作为参数传递时,堆栈上会产生COPY,对吗?这对数据成员的复制方式意味着什么?前两个是结构类型,因此副本应该由DateTime和TimeSpan组成.第三种类型是基元,因此它也被复制.但是dm_strMessage呢,它是对象的引用?当它被复制时,会创建对同一个String的另一个引用,对吧?对象本身驻留在堆中,并且不被复制(堆上只有一个实例.)所以现在我们必须引用String类型的同一对象.如果从不同的线程访问这两个引用,则可以想象String对象可能会被同时从两个不同的方向修改而被破坏.MSDN文档说System.String是线程安全的.这是否意味着String类有一个内置机制来防止对象在这里描述的情况类型中被破坏?我试图弄清楚我的MessageBox结构是否有任何潜在的缺陷/缺陷是结构与类.感谢您的任何意见.
Source.Energy.
字符串不会被多线程访问“损坏”,因为它们是不可变的。
不过,您应该避免使结构可变。阅读此问题和答案以获取更多信息。
我试图弄清楚我的 MessageBox 结构作为结构与类是否有任何潜在的缺陷/陷阱。
它可能不应该是一个结构。请参阅 MSDN 上关于在类和结构之间进行选择的指南。
除非类型具有以下所有特征,否则不要定义结构:
- 它在逻辑上表示单个值,类似于基本类型(整数、双精度等)。
- 它的实例大小小于 16 字节。
- 它是不可改变的。
- 它不必经常装箱。
我认为您的 MessageBox 肯定违反了第一条和第二条准则,也可能违反了第三条准则,具体取决于可用的方法。