0

I'm using Renci SSH.NET as SFTP client in C#.
Now I'm making a progress bar with this API. I tried with async and await, but I could not find the solution for getting downloaded bytes. I tried this way:

  1. Could you let me know problem with my code?

  2. Is there any way to try using async, await with Renci SSH.NET? And get some downloaded or uploaded bytes from API.

IAsyncResult UploadResult = sftp.BeginUploadFile(stream, remotepath + "/" + 
Path.GetFileName(localpath));

SftpUploadAsyncResult UploadProgress = new SftpUploadAsyncResult(null, UploadResult.AsyncState);

Window_Progress wp = new Window_Progress();
Point _pt = MainWindow.current.PointToScreen(new 
Point((MainWindow.current.Width - wp.Width) / 2,
(MainWindow.current.Height - wp.Height) / 2));
wp.Left = _pt.X;
wp.Top = _pt.Y;

while (!UploadProgress.IsCompleted)
{
    UploadProgress = new SftpUploadAsyncResult(null,UploadResult.AsyncState);
    Thread.Sleep(10);
    wp.PartialProgressBar.Value = (UploadProgress.UploadedBytes / 
    FilesAndDirectory.GetSize(localpath) * 100);
}

UploadProgress.AsyncWaitHandle.WaitOne();
wp.Close();
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Jonghyuk Park
  • 13
  • 1
  • 4
  • It is not clear what you are asking. Are you getting an error? If so, please copy it here. What is the problem you are seeing? – David Hempy Sep 06 '18 at 04:33

1 Answers1

0

First, your code has numerous flaws:

  • You are using "async" method, and then you synchronously wait for it to complete.
  • You even process a result in a loop, presumably from a GUI thread, without pumping a GUI message queue.
  • SftpUploadAsyncResult won't get your upload progress, when you create your own instance. Pass it the "state" object won't help. You should cast UploadResult returned by BeginUploadFile to SftpUploadAsyncResult, instead of creating a new SftpUploadAsyncResult.

Anyway, as I do not think that SftpClient class itself has any event that would trigger on upload progress, easiest solution is to use uploadCallback parameter (4th) of BeginUploadFile, the same way it's used with synchronous upload. See Displaying progress of file upload in a ProgressBar with SSH.NET.

sftp.BeginUploadFile(
    stream, remotepath + "/" + Path.GetFileName(localpath), null, null, UpdateProgresBar);

And then it's questionable whether using "async" upload has any advantage with SftpClient. There's no "async" variant for Connect method, so you need a thread/task for that anyway, so why don't you also upload a file from that thread right away?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • 1
    Oh that's Perfect!! Really thanks a lot! Hope you have a nice day – Jonghyuk Park Sep 06 '18 at 09:15
  • I agree there's not much advantage to the "async" aspect of BeginUploadFile, as you'll probably already be in a separate thread, but it does have the advantage of having a means to cancel the operation (using the IsUploadCanceled Property of SftpUploadAsyncReslut), which UploadFile's CallBack does not have, so I use it instead of UploadFile. – WATYF Feb 01 '21 at 04:22