运行异步时FTP上传不起作用,但在运行同步时有效

时间:2015-07-05 13:36:32

标签: c# ftp progress

我正在尝试通过FTP上传文件,并希望向用户报告进度。我关注this suggestion,但无法使其发挥作用。

如果我同步调用代码,它可以正常工作......

  FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://myftpserver.com/test.zip");
  request.Credentials = new NetworkCredential("uid", "pwd");
  request.Method = WebRequestMethods.Ftp.UploadFile;
  using (FileStream inputStream = File.OpenRead(@"D:\test.zip")) {
    using (Stream outputStream = request.GetRequestStream()) {
      byte[] buffer = new byte[64 * 64];
      int totalReadBytesCount = 0;
      int readBytesCount;
      while ((readBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0) {
        outputStream.Write(buffer, 0, readBytesCount);
        totalReadBytesCount += readBytesCount;
        int progress = (int)(totalReadBytesCount * 100.0 / inputStream.Length);
        Debug.WriteLine("  " + progress + "%");
      }
    }
  }

...但是如果我尝试将代码包装在BackgroundWorker中,它就会无声地失败。我试过在它周围添加一个try / catch块,但我没有例外。

以下是代码的BGW版本......

  BackgroundWorker bg = new BackgroundWorker {
    WorkerReportsProgress = true
  };
  bg.DoWork += (s, e) => {
    try {
      Debug.WriteLine("DoWork");
      FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://myftpserver.com/test.zip");
      Debug.WriteLine("DoWork - Setting up creds");
      request.Credentials = new NetworkCredential("uid", "pwd");
      request.Method = WebRequestMethods.Ftp.UploadFile;
      using (FileStream inputStream = File.OpenRead(@"D:\test.zip")) {
        using (Stream outputStream = request.GetRequestStream()) {
          byte[] buffer = new byte[64 * 64];
          int totalReadBytesCount = 0;
          int readBytesCount;
          while ((readBytesCount = inputStream.Read(buffer, 0, buffer.Length)) > 0) {
            Debug.WriteLine("  DoWork - Inside");
            outputStream.Write(buffer, 0, readBytesCount);
            totalReadBytesCount += readBytesCount;
            double progress = totalReadBytesCount * 100.0 / inputStream.Length;
            Debug.WriteLine("  " + progress + "%");
            bg.ReportProgress((int)progress);
          }
        }
      }
    }
    catch (Exception ex) {
      Debug.WriteLine("Exception: " + ex.Message);
    }
  };
  bg.ProgressChanged += (s, e) => {
    Debug.WriteLine(e.ProgressPercentage + "%");
  };
  bg.RunWorkerCompleted += (s, e) => {
    Debug.WriteLine("Done");
  };
  bg.RunWorkerAsync();
}

我将“DoWork”行写入“输出”窗口,但没有其他内容。如果我在设置FtpWebRequest的行上放置一个断点,则执行会立即在该行之后结束,但我没有得到异常。

任何想法?可能是我做错了。我想上传异步,并有一个进度指示器。这甚至是最好的方法吗?

1 个答案:

答案 0 :(得分:0)

如果它对任何人有帮助,问题与上传代码无关,这很好。问题是,为了速度(或者我认为),我在控制台应用程序中开发了这段代码。 Main()方法称为异步上载方法,然后退出。问题的原因是Main方法没有等到异步方法完成,所以执行终止。

解决问题的快捷方法是添加行......

Thread.Sleep(10000);

...在调用异步方法之后。但是,这需要猜测异步方法需要多长时间,和/或保守,并且必须等待超过必要的时间。

IWolber在this thread的答案中可以看到一个更好的方法,只需要等待所需的时间。