All packets are processed in TNet in one place -- TNet.GameServer's ThreadFunction(). This should be the only place where packets are sent out as well. Note that there is no thread locking happening, because this is the only place where sending and receiving can occur. Since you are trying to do it from a separate thread, you would have to add some kind of thread locking. It might be easier to add a queue instead, and when you want to modify the queue you'd lock it first. You would use the same queue inside ThreadFunction() -- if it's not empty, lock it, grab the first item, process it (and send out the packet), continue until it's empty. This kind of a question is really outside TNet's scope at this point -- it's a C# multi-threading question.