I am very confused about GetFileAsync when using SFtp.
If two tasks are executed and 'A' task is canceled and 'B' task is in a block state(writing is blocked for other io),
the 'A' task Wait() call is not returned until 'B' task is released.
I do not seem to understand the Async function.
In the example below, I would like you to help me understand what I do not understand.
(BeginGetFile, EndGetFile is same issue. EndGetFile is blocked)
class Program
{
static void Main(string[] args)
{
Task task1 = null;
Task task2 = null;
Sftp sftp = Connect();
if (sftp == null)
{
Console.ReadKey();
return;
}
try
{
string filename = $"/home/011.jpg";
string asyncState = filename;
task1 = sftp.GetFileAsync(filename, new WaitStream(), 0, 512 * 1024, asyncState);
Console.WriteLine($"{DateTime.Now.ToString()} Wait Task Created");
}
catch (Exception ex)
{
Console.WriteLine($"{DateTime.Now.ToString()} Wait Task Created Error : {ex.Message}");
}
try
{
string filename = $"/home/019.jpg";
string asyncState = filename;
task2 = sftp.GetFileAsync(filename, new NoWaitStream(), 0, 512 * 1024, asyncState);
Console.WriteLine($"{DateTime.Now.ToString()} NoWait Task Created");
}
catch (Exception ex)
{
Console.WriteLine($"{DateTime.Now.ToString()} NoWait Task Created Error : {ex.Message}");
}
try
{
sftp.AbortTransfer(task2.AsyncState);
Console.WriteLine($"{DateTime.Now.ToString()} NoWait Task Aborted");
task2.Wait();
Console.WriteLine($"{DateTime.Now.ToString()} NoWait Task Ended");
}
catch (Exception ex)
{
if (ex.InnerException != null)
Console.WriteLine($"{DateTime.Now.ToString()} NoWait Task Wait Error : {ex.InnerException.Message}");
else
Console.WriteLine($"{DateTime.Now.ToString()} NoWait Task Wait Error : {ex.Message}");
}
try
{
sftp.AbortTransfer(task1.AsyncState);
Console.WriteLine($"{DateTime.Now.ToString()} Wait Task Aborted");
task1.Wait();
Console.WriteLine($"{DateTime.Now.ToString()} Wait Task Ended");
}
catch (Exception ex)
{
if (ex.InnerException != null)
Console.WriteLine($"{DateTime.Now.ToString()} Wait Task Wait Error : {ex.InnerException.Message}");
else
Console.WriteLine($"{DateTime.Now.ToString()} Wait Task Wait Error : {ex.Message}");
}
Console.WriteLine($"{DateTime.Now.ToString()} Finished");
Console.ReadKey();
}
static Sftp Connect()
{
try
{
Sftp sftp = new Sftp();
sftp.MaxDownloadSpeed = 0;
sftp.MaxUploadSpeed = 0;
sftp.Settings.UseLargeBuffers = true;
sftp.Encoding = Encoding.UTF8;
sftp.Connect("192.168.0.8", 22);
sftp.Login("test", "test");
return sftp;
}
catch(Exception ex)
{
Console.WriteLine($"Connect Failed : " + ex.Message);
return null;
}
}
private class NoWaitStream : Stream
{
public override bool CanRead
{
get { return false; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
}
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
}
public override void Close()
{
base.Close();
}
}
private class WaitStream : Stream
{
public override bool CanRead
{
get { return false; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
}
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { throw new NotSupportedException(); }
set { throw new NotSupportedException(); }
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
Thread.Sleep(10000);
}
public override void Close()
{
base.Close();
}
}
}
In my case, GetDownloadStream / GetUploadStream works very well for my processing. However, performance is unsatisfactory (1 Gbps Wired Connection).
The GetDownloadStream / GetUploadStream function uses Ping / Pong Communication, so performance does not work properly.
I would like to ask if you can create GetDownloadStream / GetUploadStream using asynchronous communication like GetFile/PutFile.
For example :
Stream stream = sftp.GetBufferdDownloadStream();
...
// Cancel Transfer
stream.Close(); // don't send unsent acks
// Normal Close
stream.Flush(); // send all unsent acks
stream.Close();
Thank you.