2

I have a C# code in which I am executing on Visual Studio 2017. My aim is to start multiple threads in parallel and connect to different IPs via SSH, execute a command on these devices and return the output to the Console. An example of connecting to one such device with IP: 192.168.46.126 is as follows:

Thread myNewThread = new Thread(() => sendCommand("192.168.46.126", command));
myNewThread.Start();

The sendCommand function is as follows:

void sendCommand(string IPaddr, string command)
{
    using (var sshClient = new SshClient(IPaddr, username, password))
    {
        sshClient.Connect();
        sshClient.Runcommand(command); //Takes a lot of time to execute
    }
}

The sshClient.runCommand(command) takes a lot of time to execute. I need to run all these threads in parallel to connect to each device and print their statuses to the Console. In case a thread takes too long, I need to have a timeout option. I searched online but their seems to be no timeout option on the RunCommand function. The only timeout option seems to be on the connect() function implemented via following code:

client.ConnectionInfo.Timeout = TimeSpan.FromSeconds(10);

Is their a way I can implemet a timout for the runCommand line of code?

1
  • 2
    Instead of RunCommand use CreateCommand that will return an SshCommand instance. You can then set a timeout on that instance and execute the command from that instance. Haven't tried myself, my explanation is based on looking at the source code of the SshClient... (general advice: if you use a library and documentation is lacking, first look at all the methods/properties/fields provided by a class you want to use. If that is not revealing enough and the library is open source, take a gander at the source code. It is often rather easy to figure out how to do things this way...) Commented Feb 19, 2019 at 20:44

1 Answer 1

5

@user2819245 is correct. I had the same problem so I change my code to use CreateCommand(), defining the CommandTimeout and then invoking Execute(). Note: A try/catch is necessary around the Execute() to catch SshOperationTimeoutException. I had expected the command Result and/or Error would have been used to capture the timeout error, but alas it is not.

Here is how your code should have been updated to

void sendCommand(string IPaddr, string command)
{
    using (var sshClient = new SshClient(IPaddr, username, password))
    {
        sshClient.Connect();
        Renci.SshNet.SshCommand command = sshClient.CreateCommand(command);
        command.CommandTimeout = TimeSpan.FromSeconds(10); // 10sec timeout

        try
        {
            command.Execute();
        }
        catch (Renci.SshNet.Common.SshOperationTimeoutException)
        {
            // however you want to handle it
        } 

        client.Disconnect();      
    }
}
Sign up to request clarification or add additional context in comments.

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.