1

I am trying to use

private TcpClient tcpClient;

in a class and every time when I send a command like LIST, RETR, STOR, I used to lock the TCPClient for that particular time of execution of commands and getting response.

Now when I send the other command in between the one is executing, It isn't able to lock that tcpclient instance again.

How should I send the other command when one is executing. For all commands I need to lock the TCPClient, that I can't change.

3 Answers 3

2

This is a design problem. You need to design a multithreaded way of accessing the TcpClient without locking it excessivly

May i suggest you use a queue instead of locking the TcpClient ? I reckon your trying to build an FTP client. (i am guessing based on the LIST, RETR and STOR commands).

An example of a simple queue

private TcpClient client;
private Queue<string> commands = new Queue<string>();
private AutoResetEvent resume = new AutoResetEvent(false);

public void Add(string cmd)
{
  lock(commands) { commands.Enqueue(cmd); }
  resume.Set();

}

private void ThreadRun() // this method runs on a different thread
{
   while(!quit.WaitOne(0,true))
   {
      resume.WaitOne();
      string command;
      lock(commands) { command = commands.Dequeue(); }
      Process(command);

   }


}

You should refrain from trying to "lock" objects just to get it thread-safe. A thread-safe application is designed to operate with minimal locking, rather than forcing locks to enforce thread safety.

Sign up to request clarification or add additional context in comments.

3 Comments

it means when One command is fully executed then only again second command will execute. That's what I don't want, I want to execute the threads independently, but due to locking of TCPClient, I can't run the different threads.
The problem is not with locking of the TCP client. The problem is that you have a single TCP client that is maintaining a single connection to a server. If you want multiple commands at once, have multiple TCP clients, so you can have multiple conversations going on at once.
@Yuliy: Poor design choice to use multiple clients just to be able to send several commands.
0

Use one TcpClient for each thread.

1 Comment

is it a good way opening more than one tcpclient??If the app connects to a data server and also listens to incoming messages over it???
0

First of all. Locking is all bad when it comes to socket programming. @AndrewKeith's solution is quite good for queuing commands and to send them.

What you need is to have a request id that you can put in another queue and send it back with the response. You can have several ongoing commands by doing so.

Simple pseudo code:

public void Send(ICommand command)
{
    var myPacket = new CommandPacket {
        Command = command,
        RequestId = Guid.NewGuid()
    };
    _pendingCommands.Add(myPacket);

    var buffer = Serialize(myPacket);
    socket.Send(buffer);
}

public void OnReceive(IAsynResult ar)
{
    var bytesRead =  socket.EndRecieve(ar);
    _inStream.Write(_readBuffer, 0, bytesRead);

    if (GotCompletedPacket(_inStream))
    {
        var packet = Deserialize(_inStream);
        var waitingCommand = _pendingCommands.FirstOrDefault(p => p.RequestId == packet.RequestId);

        if (waitingCommand != null)
          //got a reply to the command.
    }

}

I would personally add a delegate when invoking the command:

public void Send(ICommand command, ICommandHandler handler)

and invoke that handler when a reply have been received.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.