Unfortunately, ConnectAsync
and other *Async
methods are not truly asynchronous. They are in fact equivalent to their synchronous variants.
We are aware of this limitation and we plan to do something about it in the future, most likely after we deprecate .NET 2.0/3.5 platforms, which would enable us to use await
/async
(that would help us tremendously to bring make codebase up-to-date).
But unfortunately, this is going to be a huge amount of work that might take months to complete. We are currently busy improving other areas (such as ECDSA and ECDH support in SSH and TLS) and can't devote any resources to this yet.
However, in this particular case, the issue is most likely caused by a "none proxy" code (basically an implementation of our Rebex.Net.ISocket
interface on top of System.Net.Sockets.Socket
) which creates an additional thread. And this might actually be quite simple to solve.
Additionally, you can even fix this yourself by implementing a custom transport layer using ISocketFactory/ISocket
interfaces and instruct the Sftp
object to use it instead of the built-in layer by calling SetSocketFactory
method before connecting.
Sample implementation:
public class CustomSocket : ISocket
{
private class CustomSocketFactory : ISocketFactory
{
public ISocket CreateSocket()
{
return new CustomSocket(this);
}
}
private static readonly ISocketFactory _factory = new CustomSocketFactory();
public static ISocketFactory Factory
{
get { return _factory; }
}
private readonly Socket _socket;
public CustomSocket(ISocketFactory factory)
{
_socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
}
public bool Connected
{
get { return _socket.Connected; }
}
public EndPoint LocalEndPoint
{
get { return _socket.LocalEndPoint; }
}
public EndPoint RemoteEndPoint
{
get { return _socket.RemoteEndPoint; }
}
public int Timeout
{
get
{
return _socket.ReceiveTimeout;
}
set
{
_socket.ReceiveTimeout = value;
_socket.SendTimeout = value;
}
}
public void Close()
{
_socket.Close();
}
public void Connect(EndPoint remoteEP)
{
_socket.Connect(remoteEP);
}
public void Connect(string serverName, int serverPort)
{
_socket.Connect(serverName, serverPort);
}
public bool Poll(int microSeconds, SocketSelectMode mode)
{
return _socket.Poll(microSeconds, (SelectMode)mode);
}
public int Receive(byte[] buffer, int offset, int count, SocketFlags socketFlags)
{
return _socket.Receive(buffer, offset, count, socketFlags);
}
public int Send(byte[] buffer, int offset, int count, SocketFlags socketFlags)
{
return _socket.Send(buffer, offset, count, socketFlags);
}
public void Shutdown(SocketShutdown how)
{
_socket.Shutdown(how);
}
}
Usage:
var sftp = new Sftp();
sftp.SetSocketFactory(CustomSocket.Factory);
sftp.Connect("test.rebex.net");
sftp.Login("demo", "password");
sftp.GetList();
sftp.Disconnect();