diff --git a/Renci.SshClient/Renci.SshNet/ChannelAsyncResult.cs b/Renci.SshClient/Renci.SshNet/ChannelAsyncResult.cs
index a52625fc..61f2ba76 100644
--- a/Renci.SshClient/Renci.SshNet/ChannelAsyncResult.cs
+++ b/Renci.SshClient/Renci.SshNet/ChannelAsyncResult.cs
@@ -62,18 +62,5 @@ namespace Renci.SshNet
{
this._command = command;
}
-
- ///
- /// Validates that command object is valid to be used with this instance.
- ///
- /// The command.
- public void ValidateCommand(SshCommand command)
- {
- if (this._command != command)
- {
- throw new InvalidOperationException("Invalid IAsyncResult parameter");
- }
-
- }
}
}
diff --git a/Renci.SshClient/Renci.SshNet/Sftp/SftpCommand.cs b/Renci.SshClient/Renci.SshNet/Sftp/SftpCommand.cs
index ca0cd7e8..fbb25d74 100644
--- a/Renci.SshClient/Renci.SshNet/Sftp/SftpCommand.cs
+++ b/Renci.SshClient/Renci.SshNet/Sftp/SftpCommand.cs
@@ -55,15 +55,6 @@ namespace Renci.SshNet.Sftp
{
this.SftpSession.WaitHandle(result.AsyncWaitHandle, this.CommandTimeout);
- if (this._callback != null)
- {
- // Execute callback on new pool thread
- Task.Factory.StartNew(() =>
- {
- this._callback(result);
- });
- }
-
if (this._error != null)
throw this._error;
@@ -200,6 +191,16 @@ namespace Renci.SshNet.Sftp
protected void CompleteExecution()
{
+ // Call callback if exists
+ if (this._callback != null)
+ {
+ // Execute callback on new pool thread
+ Task.Factory.StartNew(() =>
+ {
+ this._callback(this.AsyncResult);
+ });
+ }
+
this.AsyncResult.Complete();
this.SftpSession.AttributesMessageReceived -= SftpSession_AttributesMessageReceived;
diff --git a/Renci.SshClient/Renci.SshNet/SshCommand.cs b/Renci.SshClient/Renci.SshNet/SshCommand.cs
index 0bea40cc..1cdc6f1e 100644
--- a/Renci.SshClient/Renci.SshNet/SshCommand.cs
+++ b/Renci.SshClient/Renci.SshNet/SshCommand.cs
@@ -34,6 +34,8 @@ namespace Renci.SshNet
private bool _hasError;
+ private object _endExecuteLock = new object();
+
///
/// Gets the command text.
///
@@ -204,22 +206,31 @@ namespace Renci.SshNet
///
public string EndExecute(IAsyncResult asyncResult)
{
- CommandAsyncResult channelAsyncResult = asyncResult as CommandAsyncResult;
+ if (this._asyncResult == asyncResult && this._asyncResult != null)
+ {
+ lock (this._endExecuteLock)
+ {
+ if (this._asyncResult != null)
+ {
+ // Make sure that operation completed if not wait for it to finish
+ this.WaitHandle(this._asyncResult.AsyncWaitHandle);
- if (channelAsyncResult == null)
- throw new ArgumentException("Not valid 'asynchResult' parameter.");
+ this._channel.Close();
- channelAsyncResult.ValidateCommand(this);
-
- // Make sure that operation completed if not wait for it to finish
- this.WaitHandle(this._asyncResult.AsyncWaitHandle);
-
- this._channel.Close();
-
- this._channel = null;
-
- this._asyncResult = null;
+ this._channel = null;
+ this._asyncResult = null;
+ }
+ else
+ {
+ throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
+ }
+ }
+ }
+ else
+ {
+ throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
+ }
return this.Result;
}
@@ -237,10 +248,28 @@ namespace Renci.SshNet
///
/// Cancels command execution in asynchronous scenarios. CURRENTLY NOT IMPLEMENTED.
///
- public void Cancel()
- {
- throw new NotImplementedException();
- }
+ //public void Cancel()
+ //{
+ // if (this._channel != null && this._channel.IsOpen)
+ // {
+ // //this._channel.SendData(Encoding.ASCII.GetBytes("~."));
+ // this._channel.SendExecRequest("\0x03");
+
+ // //this._channel.SendSignalRequest("ABRT");
+ // //this._channel.SendSignalRequest("ALRM");
+ // //this._channel.SendSignalRequest("FPE");
+ // //this._channel.SendSignalRequest("HUP");
+ // //this._channel.SendSignalRequest("ILL");
+ // //this._channel.SendSignalRequest("INT");
+ // //this._channel.SendSignalRequest("PIPE");
+ // //this._channel.SendSignalRequest("QUIT");
+ // //this._channel.SendSignalRequest("SEGV");
+ // //this._channel.SendSignalRequest("TERM");
+ // //this._channel.SendSignalRequest("SEGV");
+ // //this._channel.SendSignalRequest("USR1");
+ // //this._channel.SendSignalRequest("USR2");
+ // }
+ //}
///
/// Executes the specified command text.
@@ -262,7 +291,7 @@ namespace Renci.SshNet
this._channel.ExtendedDataReceived += Channel_ExtendedDataReceived;
this._channel.RequestReceived += Channel_RequestReceived;
this._channel.Closed += Channel_Closed;
-
+
// Dispose of streams if already exists
if (this.OutputStream != null)
{
@@ -280,7 +309,7 @@ namespace Renci.SshNet
this.OutputStream = new PipeStream();
this.ExtendedOutputStream = new PipeStream();
- this._result = null;
+ this._result = null;
this._error = null;
}
@@ -311,12 +340,13 @@ namespace Renci.SshNet
}
this._asyncResult.IsCompleted = true;
+
if (this._callback != null)
{
// Execute callback on different thread
Task.Factory.StartNew(() => { this._callback(this._asyncResult); });
}
- ((EventWaitHandle)_asyncResult.AsyncWaitHandle).Set();
+ ((EventWaitHandle)this._asyncResult.AsyncWaitHandle).Set();
}
private void Channel_RequestReceived(object sender, Common.ChannelRequestEventArgs e)