在进度条上显示异步 SSH.NET SFTP 上传 (BeginUploadFile) 的进度

Display progress of asynchronous SSH.NET SFTP upload (BeginUploadFile) on progress bar

我在 C# 中使用 Renci SSH.NET 作为 SFTP 客户端。
现在我正在用这个 API 制作一个进度条。我尝试使用异步和等待,但找不到获取下载字节的解决方案。我这样试过:

  1. 你能告诉我我的代码有问题吗?

  2. 有什么方法可以尝试使用 async, await with Renci SSH.NET?并从 API.

  3. 获取一些下载或上传的字节
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();

首先,您的代码有很多缺陷:

  • 您正在使用 "async" 方法,然后您同步等待它完成。
  • 您甚至可以在一个循环中处理结果,大概来自 GUI 线程,而无需 抽取 GUI 消息队列。
  • 当您创建自己的实例时,
  • SftpUploadAsyncResult 不会获取您的上传进度。传递 "state" 对象将无济于事。您应该将 BeginUploadFile 返回的 UploadResult 转换为 SftpUploadAsyncResult,而不是创建新的 SftpUploadAsyncResult.

无论如何,因为我不认为 SftpClient class 本身有任何会触发上传进度的事件,最简单的解决方案是使用 uploadCallback 参数(第 4 个)BeginUploadFile,与同步上传的用法相同。参见

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

然后使用 "async" 上传是否比 SftpClient 有任何优势值得怀疑。 Connect 方法没有 "async" 变体,因此您无论如何都需要一个 thread/task,那么为什么不立即从该线程上传文件呢?