1

I have a multi-threaded application which communicates with a server over a TCP connection. The application would be deployed as a windows service.

The way it has been implemeted is, there is Controller which creates Communicator objects, assigns the port number, message count etc. properties to the Communicator and invokes its StartClient method to commence the dialog with the server.

Within the StartClient method, each Communicator object creates a connection to the server, using the port number and url specified by the Controller. After establishing the connection, it internally creates a thread and calls the ReadMessages method which keeps reading from the server till the message count is met and then gets closed down.

Based on the runtime conditions, there might be a need to reuse the Communicator object to talk with the server again and hence, the ReadMessages method woudl be called again.

Initially, we had been calling Dispose() method for the NetworkStream, StreamReader and StreamWriter objects when the ReadMessages method completed, but with the reconnecting scenario, it used to throw "Cannot access a disposed object" error. So, we commented out the Dispose method call for testing.

As of now, it works fine, but I am concerned that, this isnt the best way to achieve this functionlity as I am not disposing the objects ever.

I was thinking in terms of object pooling, If it is possible to have a pool of Stream objects which could be reused by different threads?

One way to tackle this can be to create a new instance of Stream objects each time the Communicator connects with the server, but I think that would be an expensive operation.

Can you please help me identify a better approach to handle the situation here so that I can reuse the Communicator object without a performance hit?

Danish Khan
  • 1,893
  • 5
  • 22
  • 35
  • What performance gains do you think that you'll get by reusing Communicator objects? – jgauffin Dec 21 '10 at 07:43
  • @jgauffin its not just about performance. There are a few tokens that the Communicator uses for validating the requests and the tokens are assigned by the Controller while instantiating these objects. We need to reuse, in order to have the token association intact. – Danish Khan Dec 21 '10 at 07:59

1 Answers1

0

The approach will be based on how frequently you need to read messages - if its occasional the n, I would recommend that you re-factor your communicator object to make "ReadMessages" operation atomic - i.e. it would connect to the server, create network stream, read messages and then dispose every thing.

VinayC
  • 47,395
  • 5
  • 59
  • 72
  • thanks @VinayC, but the Read operation is the main task and is running continuously. That is the reason why, I thought re-instantiating new objects each time would be pretty costly. – Danish Khan Dec 21 '10 at 07:32
  • @Danish, from your description, it appears to be happening in chunks (a chunk would be certain number of messages) - so my suggestion is based on how frequently chunk gets read. For example, let's say reconnection overhead is of 5 seconds and chunk gets read on average of 5 minutes then it make sense to reconnect. – VinayC Dec 21 '10 at 08:11
  • Well, had it been a single thread, I would have still considered it alright, but think about multiple threads running in parallel. Would you still feel each thread creating new instances every 5 mins or so would be a good idea? – Danish Khan Dec 21 '10 at 10:07
  • Of course, I would have to do it if there isnt another resort, but is it really the only option? – Danish Khan Dec 21 '10 at 10:08