/// <summary> /// Begins to execute the specified command asynchronously. /// </summary> /// <param name="text">The command text.</param> /// <returns>The SSH command.</returns> protected SshCommand BeginCommand(string text) { lock (this.sync) { // If the client is not connected, throw an exception. if (this.state != ClientState.Connected) { throw new SshException("Cannot execute the command on the SSH server because the client is not connected."); } // If the current client is null, do nothing. if (null == this.client) { throw new SshException("Cannot execute the command on the SSH server because the previous connection has already been released."); }; // If the current client is not connected, disconnect the client. if (!this.client.IsConnected) { // Change the state. this.state = ClientState.Disconnected; // Show a disconnected message. this.ShowMessage( Resources.ServerBusy_32, "Connection Failed", "The connection to the SSH server \'{0}\' failed unexpectedly.".FormatWith(this.client.ConnectionInfo.Host), false, (int)ApplicationConfig.MessageCloseDelay.TotalMilliseconds, (object[] parameters) => { // Call the disconnecting event handler. this.OnDisconnecting(this.client.ConnectionInfo); // Call the disconnected event handler. this.OnDisconnected(this.client.ConnectionInfo); }); // Dispose the clinet. this.client.Dispose(); this.client = null; // Throw an exception. throw new SshException("Cannot execute the command on the SSH server because the connection failed."); } // Create a new command for the current text. SshCommand command = this.client.CreateCommand(text); // Call the event handler. this.OnCommandBeginInternal(command); // Add a new command info object to the commands set. this.commands.Add(command); // Beginn execute the command asynchronously. IAsyncResult asyncResult = command.BeginExecute(this.OnEndCommand, command); // Get the command data. ThreadPool.QueueUserWorkItem((object state) => { // Set the stream as blocking. command.OutputStream.BlockLastReadBuffer = true; // Read the command data. using (PipeReader reader = new PipeReader(command.OutputStream)) { // While the command is not completed. while (!asyncResult.IsCompleted) { // Read all current data in a string. string data = reader.ReadToEnd(); // If the string null or empty, continue. if (string.IsNullOrEmpty(data)) { continue; } // Call the event handler event handler. this.OnCommandDataInternal(command, data); } } }); // Return the command. return command; } }