我正在尝试在C#中创建一个BitTorrent库作为辅助项目,以获得乐趣。但是,我遇到了一个设计问题,如果我现在不解决它,可能会在以后产生问题。
我目前有一个PeerGreeter
类,它将Socket
置于一个侦听状态,用于尝试连接到我的任何同伴,为我提供torrent中的文件。当一个对等连接时,欢迎交换握手,确保一切都有效,然后使用关联的PeerConnected
和握手信息作为处理程序参数触发Socket
事件。
我的Torrent
类是单个torrent及其所有职责的表示,它有两个列表,包含swarm中的所有对等体(封装在Peer
对象中),连接和断开连接。当greeter触发PeerConnected
事件时,Torrent
实例会在断开连接的列表中找到相应的Peer
。如果找到一个,则将其移动到连接列表,并在其实例中将Connection
类型的Socket
属性设置为greeter创建的Socket
。该属性是一个自动属性,其访问修饰符为:{ get; internal set; }
我遇到的问题是,据我所知,这不是线程安全的。如果一个线程正在使用Peer
的连接,然后另一个线程以某种方式修改该连接对象,或者处置它,则可能会产生问题。我已经考虑将Connection
属性的setter的访问修饰符设置为private
,并将其设置在构造函数中,但问题是我需要创建一个新对象来替换占位符{{断开列表中的1}}将其添加到连接列表中。
我的问题是,我应该坚持将setter设为Peer
,还是将其设为internal
,并将一个全新实例替换占位符也是一个好方法?
答案 0 :(得分:2)
出于线程安全的目的,使类型尽可能不可变将为您节省许多麻烦。将访问者设为私有(或更好,将字段标记为readonly
)并在需要进行更改时生成新实例。