This project is read-only.

Ionic.Zlib.dll and multiple operations

Nov 28, 2013 at 9:59 AM
I have one SftpClient on which I sometimes do multiple operations simultaneously. Each of these operations happens at a separate thread (I'm using a Parallel.ForEach loop). I've read around here that SftpClient can handle this, and I have not detected any problem with SftpClient itself. But I'm using Ionic.Zlib.dll for zlib compression and it gives me "strange" exceptions when multiple operations occurs. I suspect that Ionic.Zlib.dll either has a problem with thread safety (I know it's not thread safe) or multiple operations at the same time. The exceptions I'm getting is a ArgumentOutofRange exception deep inside Ionic.Zlib.dll. Does anyone has any thoughts or experience with this? I have not had any troubles when using Ionic.Zlib.dll with single operations on a single thread.

I could create a separate SftpClient for each operation, but the operations consists of Exists() and small file transfers so the overhead of creating a new connection each time would be very big. Doing the operations synchronous takes forever. I've also given thought to creating a pool but I would rather not do that.
Nov 28, 2013 at 9:01 PM
My solution was to implement a new parameter to the ConnectionInfo constructor which controls the usage of compression. Initial testing is very promising, the connection that need compression got it (only used for port forwarding), but the other ones don't. The exceptions that I got before is gone. Under is what I changed (except for all the changes to derived classes of ConnectionInfo). I hope this can help others that get stuck on this.

I replaced
public ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, params AuthenticationMethod[] authenticationMethods)
with
public ConnectionInfo(string host, int port, string username, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword, bool useCompression, params AuthenticationMethod[] authenticationMethods)
and replaced
this.CompressionAlgorithms = new Dictionary<string, Type>()
{
    //{"zlib@openssh.com", typeof(ZlibOpenSsh)}, 
    //{"zlib", typeof(Zlib)}, 
    {"none", null}, 
};
with
if (!useCompression)
{
    this.CompressionAlgorithms = new Dictionary<string, Type>()
    {
        {"none", null},
    };
}
else
{
    this.CompressionAlgorithms = new Dictionary<string, Type>()
    {
        {"zlib", typeof (Zlib)}, 
    };
}