I'm attempting to create a BitTorrent library in C# as a side project, for fun. However, I've run into a design issue that could create problems later on if I don't address it now.
I currently have a PeerGreeter
class, which puts a Socket
in a listening state for any peers that try to connect to me, to serve me files in the torrent. When a peer connects, the greeter exchanges handshakes, makes sure everything is valid, and then fires a PeerConnected
event with the associated Socket
and handshake information as handler arguments.
My Torrent
class, which is a representation of a single torrent and all its duties, has two lists of all peers in the swarm (encapsulated in a Peer
object), connected and disconnected. When the greeter fires the PeerConnected
event, the Torrent
instance finds the corresponding Peer
in the disconnected list. If it finds one, it moves it to the connected list, and sets a Connection
property of type Socket
in its instance to the Socket
created by the greeter. The property is an auto-property with the access modifiers as: { get; internal set; }
The problem I'm having is that this, as far as I know, isn't thread-safe. If one thread is working with a connection of a Peer
, and then another thread modifies that connection object somehow, or disposes it, it could create issues. I've considered setting the Connection
property's setter's access modifier to private
, and having it set in the constructor, but the problem with that is that I need to create a new object to replace the placeholder Peer
in the disconnected list to add it to the connected list.
My question is should I stick with having the setter as internal
, or is making it private
and replacing the placeholder with an entirely new instance a good approach as well?